From 50a4e8c6625694eedfc2f4db20951daed754c4a3 Mon Sep 17 00:00:00 2001 From: huanghe <31907499+ssd4561@users.noreply.github.com> Date: Thu, 11 May 2023 10:25:21 +0800 Subject: [PATCH] =?UTF-8?q?[bsp][phytium]=E9=80=82=E9=85=8Drt-thread5.0.0?= =?UTF-8?q?=20=E7=89=88=E6=9C=AC=20(#7441)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 朱耿宇 --- bsp/phytium/.gitignore | 12 +- bsp/phytium/aarch32/.config | 115 +- bsp/phytium/aarch32/.configs | 1152 +++++++++++++++++ bsp/phytium/aarch32/Kconfig | 4 +- bsp/phytium/aarch32/README.md | 96 +- bsp/phytium/aarch32/SConstruct | 5 + bsp/phytium/aarch32/applications/main.c | 2 +- bsp/phytium/aarch32/applications/mnt.c | 63 + bsp/phytium/aarch32/configs/e2000d_rtsmart | 1111 ++++++++++++++++ bsp/phytium/aarch32/configs/e2000d_rtsmart.h | 319 +++++ bsp/phytium/aarch32/configs/e2000d_rtthread | 1098 ++++++++++++++++ bsp/phytium/aarch32/configs/e2000d_rtthread.h | 308 +++++ bsp/phytium/aarch32/configs/e2000q_rtsmart | 1111 ++++++++++++++++ bsp/phytium/aarch32/configs/e2000q_rtsmart.h | 319 +++++ bsp/phytium/aarch32/configs/e2000q_rtthread | 1098 ++++++++++++++++ bsp/phytium/aarch32/configs/e2000q_rtthread.h | 308 +++++ bsp/phytium/aarch32/export_project.py | 15 + bsp/phytium/aarch32/figures/1682477587050.png | Bin 0 -> 29723 bytes bsp/phytium/aarch32/figures/aarch32_env.png | Bin 0 -> 9598 bytes bsp/phytium/aarch32/figures/ymodem_upload.png | Bin 0 -> 159452 bytes bsp/phytium/aarch32/link.lds | 18 +- bsp/phytium/aarch32/link_smart.lds | 120 ++ bsp/phytium/aarch32/makefile | 78 ++ bsp/phytium/aarch32/rtconfig.h | 71 +- bsp/phytium/aarch32/rtconfig.py | 88 +- bsp/phytium/aarch32/sdkconfig.h | 75 -- bsp/phytium/aarch64/.config | 116 +- bsp/phytium/aarch64/.configs | 1116 ++++++++++++++++ bsp/phytium/aarch64/Kconfig | 14 + bsp/phytium/aarch64/README.md | 117 +- bsp/phytium/aarch64/SConstruct | 4 + bsp/phytium/aarch64/applications/SConscript | 2 +- bsp/phytium/aarch64/applications/main.c | 6 +- bsp/phytium/aarch64/applications/mnt.c | 63 + bsp/phytium/aarch64/configs/e2000d_rtsmart | 1129 ++++++++++++++++ bsp/phytium/aarch64/configs/e2000d_rtsmart.h | 316 +++++ bsp/phytium/aarch64/configs/e2000d_rtthread | 1118 ++++++++++++++++ bsp/phytium/aarch64/configs/e2000d_rtthread.h | 306 +++++ bsp/phytium/aarch64/configs/e2000q_rtsmart | 1129 ++++++++++++++++ bsp/phytium/aarch64/configs/e2000q_rtsmart.h | 316 +++++ bsp/phytium/aarch64/configs/e2000q_rtthread | 1118 ++++++++++++++++ bsp/phytium/aarch64/configs/e2000q_rtthread.h | 306 +++++ bsp/phytium/aarch64/export_project.py | 15 + bsp/phytium/aarch64/figures/1682474861110.png | Bin 0 -> 29196 bytes bsp/phytium/aarch64/figures/aarch64_env.png | Bin 0 -> 11983 bytes bsp/phytium/aarch64/link.lds | 20 +- bsp/phytium/aarch64/link_smart.lds | 149 +++ bsp/phytium/aarch64/makefile | 79 ++ bsp/phytium/aarch64/rtconfig.h | 52 +- bsp/phytium/aarch64/rtconfig.py | 47 +- bsp/phytium/aarch64/sdkconfig.h | 71 - bsp/phytium/board/SConscript | 15 +- bsp/phytium/board/board.c | 405 +++--- bsp/phytium/board/board.h | 19 +- bsp/phytium/board/d2000/memory_map.c | 119 ++ bsp/phytium/board/d2000/parameters.c | 4 +- bsp/phytium/board/e2000/memory_map.c | 99 ++ bsp/phytium/board/e2000/q/parameters.c | 4 +- bsp/phytium/board/ft2004/memory_map.c | 91 ++ bsp/phytium/board/ft2004/parameters.c | 4 +- bsp/phytium/board/phytium_cpu.c | 89 +- bsp/phytium/board/phytium_cpu.h | 27 +- bsp/phytium/board/phytium_cpu_id.S | 218 ++++ bsp/phytium/board/secondary_cpu.c | 63 +- bsp/phytium/libraries/.ignore_format.yml | 6 + bsp/phytium/libraries/SConscript | 65 +- bsp/phytium/libraries/drivers/Kconfig | 37 +- bsp/phytium/libraries/drivers/drv_can.c | 594 +++++++++ bsp/phytium/libraries/drivers/drv_can.h | 35 + bsp/phytium/libraries/drivers/drv_qspi.c | 348 +++++ bsp/phytium/libraries/drivers/drv_qspi.h | 33 + bsp/phytium/libraries/drivers/drv_spi.c | 338 +++++ bsp/phytium/libraries/drivers/drv_spi.h | 28 + bsp/phytium/libraries/drivers/drv_usart.c | 46 +- bsp/phytium/libraries/drivers/drv_usart.h | 2 +- bsp/phytium/libraries/drivers/drv_xmac.c | 22 + bsp/phytium/libraries/drivers/drv_xmac.h | 22 + .../libraries/examples/spi_sfud_sample.c | 79 ++ bsp/phytium/libraries/standalone/README.md | 85 +- .../standalone/arch/armv8/aarch32/faarch32.h | 416 ------ .../arch/armv8/aarch32/fgeneric_timer.c | 154 --- .../libraries/standalone/board/Kconfig | 11 +- .../standalone/board/common/fcpu_asm.S | 2 +- .../standalone/board/common/fcpu_info.c | 216 ++-- .../board/{e2000 => common}/fearly_uart.c | 2 +- .../board/{e2000 => common}/fearly_uart.h | 6 +- .../standalone/board/d2000/fioctrl.c | 406 ++++++ .../standalone/board/d2000/fioctrl.h | 83 ++ .../standalone/board/d2000/fparameters.h | 347 +++++ .../standalone/board/e2000/d/fiopad_config.c | 673 +++++----- .../standalone/board/e2000/d/fparameters.h | 2 +- .../standalone/board/e2000/fiopad_comm.c | 20 +- .../standalone/board/e2000/fiopad_comm.h | 4 +- .../standalone/board/e2000/fparameters_comm.h | 571 ++++---- .../standalone/board/e2000/q/fiopad_config.c | 702 +++++----- .../standalone/board/e2000/q/fparameters.h | 2 +- .../standalone/board/e2000/s/fiopad_config.c | 388 +++--- .../standalone/board/e2000/s/fparameters.h | 2 +- .../standalone/board/ft2004/fioctrl.c | 348 +++++ .../standalone/board/ft2004/fioctrl.h | 81 ++ .../standalone/board/ft2004/fparameters.h | 327 +++++ .../libraries/standalone/common/Kconfig | 15 +- .../libraries/standalone/common/fassert.c | 10 +- .../libraries/standalone/common/fassert.h | 20 +- .../libraries/standalone/common/fdebug.c | 57 +- .../libraries/standalone/common/fdebug.h | 52 +- .../libraries/standalone/common/felf.c | 987 ++++++++++++++ .../armv8/aarch32/fsmc.h => common/felf.h} | 36 +- .../libraries/standalone/common/ferror_code.h | 20 +- bsp/phytium/libraries/standalone/common/fio.h | 8 +- .../standalone/{arch => }/common/fkernel.h | 169 ++- .../libraries/standalone/common/fpinctrl.h | 8 +- .../libraries/standalone/common/fprintf.c | 27 +- .../libraries/standalone/common/fprintf.h | 11 +- .../libraries/standalone/common/fprintk.c | 413 +++--- .../libraries/standalone/common/fprintk.h | 13 +- .../libraries/standalone/common/fswap.h | 64 + .../libraries/standalone/common/ftypes.h | 14 +- .../libraries/standalone/doc/ChangeLog.md | 618 ++++++++- .../standalone/doc/driver_template/foox_hw.c | 2 +- .../standalone/doc/driver_template/foox_hw.h | 2 +- .../doc/driver_template/foox_options.c | 2 +- .../doc/driver_template/foox_role.c | 2 +- .../standalone/doc/driver_template/fooxx.c | 2 +- .../standalone/doc/driver_template/fooxx.h | 2 +- .../standalone/doc/driver_template/fooxx_g.c | 2 +- .../doc/driver_template/fooxx_sinit.c | 2 +- .../standalone/doc/fig/disk_manager.png | Bin 0 -> 160171 bytes .../libraries/standalone/doc/fig/sd_image.png | Bin 0 -> 8537 bytes .../standalone/doc/fig/sd_insert.png | Bin 0 -> 700215 bytes .../standalone/doc/fig/sd_partinfo.png | Bin 0 -> 14651 bytes .../standalone/doc/fig/sd_segement.png | Bin 0 -> 6114 bytes .../libraries/standalone/doc/fig/usb_disk.png | Bin 0 -> 6645 bytes .../standalone/doc/fig/usb_image.png | Bin 0 -> 21222 bytes .../standalone/doc/fig/usb_insert.png | Bin 0 -> 562047 bytes .../standalone/doc/reference/driver/fadc.md | 4 +- .../standalone/doc/reference/driver/fcan.md | 4 +- .../standalone/doc/reference/driver/fgdma.md | 36 +- .../standalone/doc/reference/driver/fi2c.md | 2 +- .../standalone/doc/reference/driver/fmedia.md | 369 ++++++ .../standalone/doc/reference/driver/fpwm.md | 4 +- .../doc/reference/driver/fscmi_mhu.md | 282 ++++ .../standalone/doc/reference/driver/fsdio.md | 30 +- .../standalone/doc/reference/driver/fsdmmc.md | 5 +- .../standalone/doc/reference/driver/fxmac.md | 6 +- .../doc/reference/sdk/flwip_port.md | 182 +++ .../standalone/doc/reference/usr/usage.md | 128 ++ .../libraries/standalone/drivers/Kconfig | 40 +- .../libraries/standalone/drivers/adc/Kconfig | 2 +- .../standalone/drivers/adc/fadc/fadc.c | 66 +- .../standalone/drivers/adc/fadc/fadc.h | 20 +- .../standalone/drivers/adc/fadc/fadc_g.c | 23 +- .../standalone/drivers/adc/fadc/fadc_hw.c | 27 +- .../standalone/drivers/adc/fadc/fadc_hw.h | 17 +- .../standalone/drivers/adc/fadc/fadc_intr.c | 6 +- .../standalone/drivers/adc/fadc/fadc_sinit.c | 13 +- .../libraries/standalone/drivers/can/Kconfig | 4 +- .../standalone/drivers/can/fcan/fcan.c | 289 +++-- .../standalone/drivers/can/fcan/fcan.h | 38 +- .../standalone/drivers/can/fcan/fcan_g.c | 23 +- .../standalone/drivers/can/fcan/fcan_hw.c | 45 +- .../standalone/drivers/can/fcan/fcan_hw.h | 25 +- .../standalone/drivers/can/fcan/fcan_intr.c | 47 +- .../standalone/drivers/can/fcan/fcan_sinit.c | 15 +- .../libraries/standalone/drivers/dma/Kconfig | 4 +- .../standalone/drivers/dma/fddma/fddma.c | 54 +- .../standalone/drivers/dma/fddma/fddma.h | 14 +- .../standalone/drivers/dma/fddma/fddma_g.c | 2 +- .../standalone/drivers/dma/fddma/fddma_hw.c | 54 +- .../standalone/drivers/dma/fddma/fddma_hw.h | 16 +- .../standalone/drivers/dma/fddma/fddma_intr.c | 6 +- .../drivers/dma/fddma/fddma_selftest.c | 4 +- .../drivers/dma/fddma/fddma_sinit.c | 4 +- .../standalone/drivers/dma/fgdma/fgdma.c | 83 +- .../standalone/drivers/dma/fgdma/fgdma.h | 96 +- .../standalone/drivers/dma/fgdma/fgdma_g.c | 31 +- .../standalone/drivers/dma/fgdma/fgdma_hw.h | 26 +- .../standalone/drivers/dma/fgdma/fgdma_intr.c | 53 +- .../drivers/dma/fgdma/fgdma_selftest.c | 8 +- .../drivers/dma/fgdma/fgdma_sinit.c | 6 +- .../libraries/standalone/drivers/eth/Kconfig | 6 +- .../standalone/drivers/eth/fgmac/fgmac.c | 37 +- .../standalone/drivers/eth/fgmac/fgmac.h | 17 +- .../standalone/drivers/eth/fgmac/fgmac_dma.c | 15 +- .../standalone/drivers/eth/fgmac/fgmac_g.c | 29 +- .../standalone/drivers/eth/fgmac/fgmac_hw.c | 11 +- .../standalone/drivers/eth/fgmac/fgmac_hw.h | 20 +- .../standalone/drivers/eth/fgmac/fgmac_intr.c | 4 +- .../drivers/eth/fgmac/fgmac_sinit.c | 8 +- .../eth/fgmac/phy/ar803x/fgmac_ar803x.c | 19 +- .../eth/fgmac/phy/ar803x/fgmac_ar803x.h | 18 +- .../drivers/eth/fgmac/phy/fgmac_phy.c | 120 +- .../drivers/eth/fgmac/phy/fgmac_phy.h | 20 +- .../standalone/drivers/eth/fxmac/fxmac.c | 268 +++- .../standalone/drivers/eth/fxmac/fxmac.h | 46 +- .../standalone/drivers/eth/fxmac/fxmac_bd.h | 73 +- .../drivers/eth/fxmac/fxmac_bdring.c | 23 +- .../drivers/eth/fxmac/fxmac_bdring.h | 14 +- .../drivers/eth/fxmac/fxmac_debug.c | 105 ++ .../standalone/drivers/eth/fxmac/fxmac_g.c | 124 +- .../standalone/drivers/eth/fxmac/fxmac_hw.h | 299 ++--- .../standalone/drivers/eth/fxmac/fxmac_intr.c | 106 +- .../drivers/eth/fxmac/fxmac_options.c | 26 +- .../standalone/drivers/eth/fxmac/fxmac_phy.c | 96 +- .../standalone/drivers/eth/fxmac/fxmac_phy.h | 8 +- .../drivers/eth/fxmac/fxmac_sinit.c | 9 +- .../drivers/eth/fxmac/phy/eth_ieee_reg.h | 13 +- .../drivers/eth/fxmac/phy/yt/phy_yt.c | 60 +- .../drivers/eth/fxmac/phy/yt/phy_yt.h | 10 +- .../libraries/standalone/drivers/gic/Kconfig | 2 +- .../standalone/drivers/gic/fgic/fgic.c | 25 +- .../standalone/drivers/gic/fgic/fgic.h | 15 +- .../drivers/gic/fgic/fgic_cpu_interface.S | 6 +- .../drivers/gic/fgic/fgic_cpu_interface.h | 35 +- .../drivers/gic/fgic/fgic_distributor.h | 17 +- .../standalone/drivers/gic/fgic/fgic_g.c | 6 +- .../standalone/drivers/gic/fgic/fgic_hw.h | 16 +- .../drivers/gic/fgic/fgic_redistributor.h | 16 +- .../standalone/drivers/gic/fgic/fgic_sinit.c | 5 +- .../libraries/standalone/drivers/i2c/Kconfig | 4 +- .../standalone/drivers/i2c/fi2c/fi2c.c | 26 +- .../standalone/drivers/i2c/fi2c/fi2c.h | 21 +- .../standalone/drivers/i2c/fi2c/fi2c_g.c | 109 +- .../standalone/drivers/i2c/fi2c/fi2c_hw.c | 82 +- .../standalone/drivers/i2c/fi2c/fi2c_hw.h | 19 +- .../standalone/drivers/i2c/fi2c/fi2c_intr.c | 18 +- .../standalone/drivers/i2c/fi2c/fi2c_master.c | 61 +- .../standalone/drivers/i2c/fi2c/fi2c_sinit.c | 14 +- .../libraries/standalone/drivers/ipc/Kconfig | 4 +- .../drivers/ipc/fsemaphore/fsemaphore.c | 38 +- .../drivers/ipc/fsemaphore/fsemaphore.h | 15 +- .../drivers/ipc/fsemaphore/fsemaphore_g.c | 2 +- .../drivers/ipc/fsemaphore/fsemaphore_hw.h | 16 +- .../drivers/ipc/fsemaphore/fsemaphore_sinit.c | 2 +- .../standalone/drivers/media/Kconfig | 22 + .../drivers/media/fdcdp_lib/inc/fdc.h | 359 +++++ .../media/fdcdp_lib/inc/fdc_common_hw.h} | 35 +- .../drivers/media/fdcdp_lib/inc/fdc_hw.h | 200 +++ .../drivers/media/fdcdp_lib/inc/fdcdp.h | 115 ++ .../media/fdcdp_lib/inc/fdcdp_multi_display.h | 44 + .../drivers/media/fdcdp_lib/inc/fdcdp_param.h | 66 + .../drivers/media/fdcdp_lib/inc/fdp.h | 190 +++ .../drivers/media/fdcdp_lib/inc/fdp_aux.h | 75 ++ .../drivers/media/fdcdp_lib/inc/fdp_hw.h | 157 +++ .../drivers/media/fdcdp_lib/inc/fdp_phy.h | 349 +++++ .../libraries/standalone/drivers/mio/Kconfig | 2 +- .../standalone/drivers/mio/fmio/fmio.c | 116 +- .../standalone/drivers/mio/fmio/fmio.h | 11 +- .../standalone/drivers/mio/fmio/fmio_g.c | 140 +- .../standalone/drivers/mio/fmio/fmio_hw.c | 4 +- .../standalone/drivers/mio/fmio/fmio_hw.h | 22 +- .../standalone/drivers/mio/fmio/fmio_sinit.c | 10 +- .../libraries/standalone/drivers/mmc/Kconfig | 6 +- .../standalone/drivers/mmc/fsdio/fsdio.c | 141 +- .../standalone/drivers/mmc/fsdio/fsdio.h | 56 +- .../standalone/drivers/mmc/fsdio/fsdio_cmd.c | 61 +- .../standalone/drivers/mmc/fsdio/fsdio_dma.c | 109 +- .../standalone/drivers/mmc/fsdio/fsdio_g.c | 26 +- .../standalone/drivers/mmc/fsdio/fsdio_hw.h | 75 +- .../standalone/drivers/mmc/fsdio/fsdio_intr.c | 59 +- .../standalone/drivers/mmc/fsdio/fsdio_pio.c | 58 +- .../drivers/mmc/fsdio/fsdio_selftest.c | 31 +- .../drivers/mmc/fsdio/fsdio_sinit.c | 6 +- .../standalone/drivers/mmc/fsdmmc/fsdmmc.c | 47 +- .../standalone/drivers/mmc/fsdmmc/fsdmmc.h | 23 +- .../drivers/mmc/fsdmmc/fsdmmc_dma.c | 12 +- .../drivers/mmc/fsdmmc/fsdmmc_dma.h | 10 +- .../standalone/drivers/mmc/fsdmmc/fsdmmc_g.c | 17 +- .../standalone/drivers/mmc/fsdmmc/fsdmmc_hw.c | 43 +- .../standalone/drivers/mmc/fsdmmc/fsdmmc_hw.h | 22 +- .../drivers/mmc/fsdmmc/fsdmmc_intr.c | 85 +- .../drivers/mmc/fsdmmc/fsdmmc_sinit.c | 9 +- .../libraries/standalone/drivers/nand/Kconfig | 42 +- .../standalone/drivers/nand/fnand/fnand.c | 14 +- .../standalone/drivers/nand/fnand/fnand.h | 24 +- .../standalone/drivers/nand/fnand/fnand_bbm.c | 109 +- .../standalone/drivers/nand/fnand/fnand_bbm.h | 42 +- .../drivers/nand/fnand/fnand_common_cmd.c | 12 +- .../drivers/nand/fnand/fnand_common_cmd.h | 31 +- .../standalone/drivers/nand/fnand/fnand_dma.c | 20 +- .../standalone/drivers/nand/fnand/fnand_dma.h | 12 +- .../standalone/drivers/nand/fnand/fnand_ecc.c | 162 ++- .../standalone/drivers/nand/fnand/fnand_ecc.h | 19 +- .../standalone/drivers/nand/fnand/fnand_g.c | 5 +- .../standalone/drivers/nand/fnand/fnand_hw.c | 3 +- .../standalone/drivers/nand/fnand/fnand_hw.h | 18 +- .../standalone/drivers/nand/fnand/fnand_id.c | 28 +- .../standalone/drivers/nand/fnand/fnand_id.h | 15 +- .../drivers/nand/fnand/fnand_intr.c | 3 +- .../drivers/nand/fnand/fnand_option.c | 17 +- .../drivers/nand/fnand/fnand_sinit.c | 4 +- .../drivers/nand/fnand/fnand_timing.c | 175 +-- .../drivers/nand/fnand/fnand_timing.h | 19 +- .../nand/fnand/manufacturer/fnand_onfi.c | 17 +- .../nand/fnand/manufacturer/fnand_onfi.h | 14 +- .../nand/fnand/manufacturer/fnand_toggle.c | 17 +- .../nand/fnand/manufacturer/fnand_toggle.h | 33 +- .../nand/fnand/manufacturer/fnand_toshiba.c | 15 +- .../libraries/standalone/drivers/pcie/Kconfig | 2 +- .../standalone/drivers/pcie/fpcie/fpcie.c | 304 +++-- .../standalone/drivers/pcie/fpcie/fpcie.h | 35 +- .../drivers/pcie/fpcie/fpcie_common.h | 28 +- .../drivers/pcie/fpcie/fpcie_config.c | 8 +- .../standalone/drivers/pcie/fpcie/fpcie_dma.c | 19 +- .../standalone/drivers/pcie/fpcie/fpcie_dma.h | 15 +- .../standalone/drivers/pcie/fpcie/fpcie_ep.c | 21 +- .../standalone/drivers/pcie/fpcie/fpcie_g.c | 71 +- .../standalone/drivers/pcie/fpcie/fpcie_hw.c | 19 +- .../standalone/drivers/pcie/fpcie/fpcie_hw.h | 22 +- .../pcie/fpcie/{fpcir_intx.c => fpcie_intr.c} | 132 +- .../pcie/fpcie/{fpcir_intx.h => fpcie_intr.h} | 13 +- .../drivers/pcie/fpcie/fpcie_misc.c | 59 +- .../drivers/pcie/fpcie/fpcie_sinit.c | 12 +- .../standalone/drivers/pin/fgpio/Kconfig | 4 +- .../standalone/drivers/pin/fgpio/fgpio.c | 36 +- .../standalone/drivers/pin/fgpio/fgpio.h | 27 +- .../standalone/drivers/pin/fgpio/fgpio_g.c | 88 +- .../standalone/drivers/pin/fgpio/fgpio_hw.h | 23 +- .../standalone/drivers/pin/fgpio/fgpio_intr.c | 52 +- .../drivers/pin/fgpio/fgpio_selftest.c | 4 +- .../drivers/pin/fgpio/fgpio_sinit.c | 20 +- .../libraries/standalone/drivers/pwm/Kconfig | 2 +- .../standalone/drivers/pwm/fpwm/fpwm.c | 112 +- .../standalone/drivers/pwm/fpwm/fpwm.h | 24 +- .../standalone/drivers/pwm/fpwm/fpwm_g.c | 109 +- .../standalone/drivers/pwm/fpwm/fpwm_hw.c | 15 +- .../standalone/drivers/pwm/fpwm/fpwm_hw.h | 20 +- .../standalone/drivers/pwm/fpwm/fpwm_intr.c | 11 +- .../standalone/drivers/pwm/fpwm/fpwm_sinit.c | 13 +- .../libraries/standalone/drivers/qspi/Kconfig | 4 +- .../standalone/drivers/qspi/fqspi/fqspi.c | 67 +- .../standalone/drivers/qspi/fqspi/fqspi.h | 8 +- .../drivers/qspi/fqspi/fqspi_flash.c | 403 +++--- .../drivers/qspi/fqspi/fqspi_flash.h | 56 +- .../standalone/drivers/qspi/fqspi/fqspi_g.c | 14 +- .../standalone/drivers/qspi/fqspi/fqspi_hw.c | 7 +- .../standalone/drivers/qspi/fqspi/fqspi_hw.h | 25 +- .../drivers/qspi/fqspi/fqspi_sinit.c | 15 +- .../libraries/standalone/drivers/rtc/Kconfig | 2 +- .../standalone/drivers/rtc/frtc/frtc.c | 18 +- .../standalone/drivers/rtc/frtc/frtc.h | 22 +- .../standalone/drivers/rtc/frtc/frtc_g.c | 8 +- .../standalone/drivers/rtc/frtc/frtc_hw.c | 7 +- .../standalone/drivers/rtc/frtc/frtc_hw.h | 21 +- .../standalone/drivers/rtc/frtc/frtc_intr.c | 8 +- .../standalone/drivers/rtc/frtc/frtc_sinit.c | 7 +- .../libraries/standalone/drivers/sata/Kconfig | 2 +- .../standalone/drivers/sata/fsata/fsata.c | 65 +- .../standalone/drivers/sata/fsata/fsata.h | 23 +- .../standalone/drivers/sata/fsata/fsata_g.c | 18 +- .../standalone/drivers/sata/fsata/fsata_hw.c | 3 +- .../standalone/drivers/sata/fsata/fsata_hw.h | 19 +- .../drivers/sata/fsata/fsata_intr.c | 49 +- .../drivers/sata/fsata/fsata_sinit.c | 8 +- .../libraries/standalone/drivers/scmi/Kconfig | 7 + .../standalone/drivers/scmi/fscmi_mhu/fmhu.c | 75 ++ .../standalone/drivers/scmi/fscmi_mhu/fmhu.h | 87 ++ .../drivers/scmi/fscmi_mhu/fmhu_g.c | 40 + .../drivers/scmi/fscmi_mhu/fmhu_hw.h | 144 +++ .../scmi/fscmi_mhu/fmhu_intr.c} | 45 +- .../standalone/drivers/scmi/fscmi_mhu/fscmi.c | 347 +++++ .../standalone/drivers/scmi/fscmi_mhu/fscmi.h | 216 ++++ .../drivers/scmi/fscmi_mhu/fscmi_base.c | 371 ++++++ .../drivers/scmi/fscmi_mhu/fscmi_base.h | 60 + .../drivers/scmi/fscmi_mhu/fscmi_perf.c | 543 ++++++++ .../drivers/scmi/fscmi_mhu/fscmi_perf.h | 114 ++ .../drivers/scmi/fscmi_mhu/fscmi_sensors.c | 365 ++++++ .../drivers/scmi/fscmi_mhu/fscmi_sensors.h | 114 ++ .../standalone/drivers/serial/Kconfig | 2 +- .../standalone/drivers/serial/fpl011/fpl011.c | 25 +- .../standalone/drivers/serial/fpl011/fpl011.h | 25 +- .../drivers/serial/fpl011/fpl011_g.c | 9 +- .../drivers/serial/fpl011/fpl011_hw.c | 12 +- .../drivers/serial/fpl011/fpl011_hw.h | 29 +- .../drivers/serial/fpl011/fpl011_intr.c | 8 +- .../drivers/serial/fpl011/fpl011_options.c | 34 +- .../drivers/serial/fpl011/fpl011_sinit.c | 6 +- .../libraries/standalone/drivers/spi/Kconfig | 5 +- .../standalone/drivers/spi/fspim/fspim.c | 194 ++- .../standalone/drivers/spi/fspim/fspim.h | 45 +- .../standalone/drivers/spi/fspim/fspim_g.c | 18 +- .../standalone/drivers/spi/fspim/fspim_hw.c | 136 +- .../standalone/drivers/spi/fspim/fspim_hw.h | 31 +- .../standalone/drivers/spi/fspim/fspim_intr.c | 6 +- .../drivers/spi/fspim/fspim_selftest.c | 4 +- .../drivers/spi/fspim/fspim_sinit.c | 12 +- .../drivers/timer/ftimer_tacho/ftacho.c | 17 +- .../drivers/timer/ftimer_tacho/ftimer.c | 59 +- .../drivers/timer/ftimer_tacho/ftimer_tacho.h | 15 +- .../timer/ftimer_tacho/ftimer_tacho_g.c | 7 +- .../timer/ftimer_tacho/ftimer_tacho_hw.h | 19 +- .../timer/ftimer_tacho/ftimer_tacho_intr.c | 8 +- .../libraries/standalone/drivers/usb/Kconfig | 4 +- .../libraries/standalone/drivers/usb/fusb.c | 308 +++-- .../libraries/standalone/drivers/usb/fusb.h | 16 +- .../standalone/drivers/usb/fusb_debug.c | 14 +- .../standalone/drivers/usb/fusb_def.h | 15 +- .../standalone/drivers/usb/fusb_dev.c | 98 +- .../libraries/standalone/drivers/usb/fusb_g.c | 2 +- .../standalone/drivers/usb/fusb_generic_hub.c | 66 +- .../standalone/drivers/usb/fusb_generic_hub.h | 10 +- .../standalone/drivers/usb/fusb_hid.c | 155 ++- .../standalone/drivers/usb/fusb_hid.h | 14 +- .../standalone/drivers/usb/fusb_hub.c | 28 +- .../standalone/drivers/usb/fusb_hub.h | 14 +- .../standalone/drivers/usb/fusb_msc.c | 122 +- .../standalone/drivers/usb/fusb_msc.h | 14 +- .../standalone/drivers/usb/fusb_private.h | 18 +- .../standalone/drivers/usb/fusb_sinit.c | 2 +- .../standalone/drivers/usb/fxhci/fxhci.c | 120 +- .../standalone/drivers/usb/fxhci/fxhci.h | 13 +- .../standalone/drivers/usb/fxhci/fxhci_cmd.c | 28 +- .../drivers/usb/fxhci/fxhci_debug.c | 12 +- .../standalone/drivers/usb/fxhci/fxhci_dev.c | 130 +- .../standalone/drivers/usb/fxhci/fxhci_evt.c | 112 +- .../standalone/drivers/usb/fxhci/fxhci_hw.c | 132 +- .../standalone/drivers/usb/fxhci/fxhci_hw.h | 19 +- .../drivers/usb/fxhci/fxhci_private.h | 34 +- .../drivers/usb/fxhci/fxhci_roothub.c | 6 +- .../standalone/drivers/watchdog/Kconfig | 2 +- .../standalone/drivers/watchdog/fwdt/fwdt.c | 26 +- .../standalone/drivers/watchdog/fwdt/fwdt.h | 20 +- .../standalone/drivers/watchdog/fwdt/fwdt_g.c | 105 +- .../drivers/watchdog/fwdt/fwdt_hw.c | 34 +- .../drivers/watchdog/fwdt/fwdt_hw.h | 21 +- .../drivers/watchdog/fwdt/fwdt_intr.c | 3 +- .../drivers/watchdog/fwdt/fwdt_sinit.c | 9 +- bsp/phytium/libraries/standalone/gitinfo | 7 +- .../port/arch/armv8/aarch32/fcache.c | 56 + .../port/arch/armv8/aarch32/fcp15.c | 39 + .../port/arch/armv8/aarch32/fcp15.h | 59 + .../port/arch/armv8/aarch32/fgeneric_timer.c | 93 ++ .../{ => port}/arch/armv8/aarch32/fpsci.c | 5 +- .../{ => port}/arch/armv8/aarch32/fpsci.h | 7 +- .../port/arch/armv8/aarch32/fsleep.c | 53 + .../standalone/port/arch/armv8/aarch32/fsmc.h | 76 ++ .../arch/armv8/aarch32}/fsmccc_call.S | 3 +- .../port/arch/armv8/aarch32/sdkopts.h | 61 + .../port/arch/armv8/aarch64/faarch64.c | 39 + .../port/arch/armv8/aarch64/faarch64.h | 53 + .../arch/armv8/aarch64/farm_smccc.h | 22 +- .../port/arch/armv8/aarch64/fcache.c_x | 52 + .../port/arch/armv8/aarch64/fgeneric_timer.c | 112 ++ .../{ => port}/arch/armv8/aarch64/fpsci.c | 14 +- .../port/arch/armv8/aarch64/fpsci.h | 66 + .../port/arch/armv8/aarch64/fsleep.c | 71 + .../arch/armv8/aarch64}/fsmccc_call.S | 5 +- .../port/arch/armv8/aarch64/sdkopts.h | 61 + .../libraries/standalone/port/arch/fcache.h | 55 + .../aarch32 => port/arch}/fgeneric_timer.h | 35 +- .../standalone/{common => port/arch}/fsleep.h | 21 +- .../libraries/standalone/port/sdkconfig.h | 90 ++ bsp/phytium/tools/figures/commit_id.png | Bin 0 -> 23085 bytes bsp/phytium/tools/figures/commit_reduce.png | Bin 0 -> 17328 bytes bsp/phytium/tools/figures/rebase_commit.png | Bin 0 -> 11669 bytes bsp/phytium/tools/figures/rebase_done.png | Bin 0 -> 101318 bytes bsp/phytium/tools/figures/reduce_rtt.png | Bin 0 -> 50663 bytes bsp/phytium/tools/lite_tools.md | 44 + bsp/phytium/tools/reduce_rtt_code.py | 130 ++ libcpu/aarch64/common/context_gcc.S | 2 +- libcpu/aarch64/common/gicv3.c | 6 +- libcpu/aarch64/common/gicv3.h | 7 +- libcpu/aarch64/common/interrupt.c | 4 +- libcpu/aarch64/cortex-a/entry_point.S | 5 +- libcpu/arm/cortex-a/cpuport.c | 2 +- libcpu/arm/cortex-a/interrupt.c | 3 +- libcpu/arm/cortex-a/start_gcc.S | 101 +- src/mem.c | 3 +- 468 files changed, 35041 insertions(+), 7087 deletions(-) create mode 100644 bsp/phytium/aarch32/.configs create mode 100644 bsp/phytium/aarch32/applications/mnt.c create mode 100644 bsp/phytium/aarch32/configs/e2000d_rtsmart create mode 100644 bsp/phytium/aarch32/configs/e2000d_rtsmart.h create mode 100644 bsp/phytium/aarch32/configs/e2000d_rtthread create mode 100644 bsp/phytium/aarch32/configs/e2000d_rtthread.h create mode 100644 bsp/phytium/aarch32/configs/e2000q_rtsmart create mode 100644 bsp/phytium/aarch32/configs/e2000q_rtsmart.h create mode 100644 bsp/phytium/aarch32/configs/e2000q_rtthread create mode 100644 bsp/phytium/aarch32/configs/e2000q_rtthread.h create mode 100644 bsp/phytium/aarch32/figures/1682477587050.png create mode 100644 bsp/phytium/aarch32/figures/aarch32_env.png create mode 100644 bsp/phytium/aarch32/figures/ymodem_upload.png create mode 100644 bsp/phytium/aarch32/link_smart.lds create mode 100644 bsp/phytium/aarch32/makefile delete mode 100644 bsp/phytium/aarch32/sdkconfig.h create mode 100644 bsp/phytium/aarch64/.configs create mode 100644 bsp/phytium/aarch64/applications/mnt.c create mode 100644 bsp/phytium/aarch64/configs/e2000d_rtsmart create mode 100644 bsp/phytium/aarch64/configs/e2000d_rtsmart.h create mode 100644 bsp/phytium/aarch64/configs/e2000d_rtthread create mode 100644 bsp/phytium/aarch64/configs/e2000d_rtthread.h create mode 100644 bsp/phytium/aarch64/configs/e2000q_rtsmart create mode 100644 bsp/phytium/aarch64/configs/e2000q_rtsmart.h create mode 100644 bsp/phytium/aarch64/configs/e2000q_rtthread create mode 100644 bsp/phytium/aarch64/configs/e2000q_rtthread.h create mode 100644 bsp/phytium/aarch64/figures/1682474861110.png create mode 100644 bsp/phytium/aarch64/figures/aarch64_env.png create mode 100644 bsp/phytium/aarch64/link_smart.lds create mode 100644 bsp/phytium/aarch64/makefile delete mode 100644 bsp/phytium/aarch64/sdkconfig.h create mode 100644 bsp/phytium/board/d2000/memory_map.c create mode 100644 bsp/phytium/board/e2000/memory_map.c create mode 100644 bsp/phytium/board/ft2004/memory_map.c create mode 100644 bsp/phytium/board/phytium_cpu_id.S create mode 100644 bsp/phytium/libraries/.ignore_format.yml create mode 100644 bsp/phytium/libraries/drivers/drv_can.c create mode 100644 bsp/phytium/libraries/drivers/drv_can.h create mode 100644 bsp/phytium/libraries/drivers/drv_qspi.c create mode 100644 bsp/phytium/libraries/drivers/drv_qspi.h create mode 100644 bsp/phytium/libraries/drivers/drv_spi.c create mode 100644 bsp/phytium/libraries/drivers/drv_spi.h create mode 100644 bsp/phytium/libraries/drivers/drv_xmac.c create mode 100644 bsp/phytium/libraries/drivers/drv_xmac.h create mode 100644 bsp/phytium/libraries/examples/spi_sfud_sample.c delete mode 100644 bsp/phytium/libraries/standalone/arch/armv8/aarch32/faarch32.h delete mode 100644 bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.c rename bsp/phytium/libraries/standalone/board/{e2000 => common}/fearly_uart.c (98%) rename bsp/phytium/libraries/standalone/board/{e2000 => common}/fearly_uart.h (96%) create mode 100644 bsp/phytium/libraries/standalone/board/d2000/fioctrl.c create mode 100644 bsp/phytium/libraries/standalone/board/d2000/fioctrl.h create mode 100644 bsp/phytium/libraries/standalone/board/d2000/fparameters.h create mode 100644 bsp/phytium/libraries/standalone/board/ft2004/fioctrl.c create mode 100644 bsp/phytium/libraries/standalone/board/ft2004/fioctrl.h create mode 100644 bsp/phytium/libraries/standalone/board/ft2004/fparameters.h create mode 100644 bsp/phytium/libraries/standalone/common/felf.c rename bsp/phytium/libraries/standalone/{arch/armv8/aarch32/fsmc.h => common/felf.h} (62%) rename bsp/phytium/libraries/standalone/{arch => }/common/fkernel.h (59%) create mode 100644 bsp/phytium/libraries/standalone/common/fswap.h create mode 100644 bsp/phytium/libraries/standalone/doc/fig/disk_manager.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/sd_image.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/sd_insert.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/sd_partinfo.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/sd_segement.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/usb_disk.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/usb_image.png create mode 100644 bsp/phytium/libraries/standalone/doc/fig/usb_insert.png create mode 100644 bsp/phytium/libraries/standalone/doc/reference/driver/fmedia.md create mode 100644 bsp/phytium/libraries/standalone/doc/reference/driver/fscmi_mhu.md create mode 100644 bsp/phytium/libraries/standalone/doc/reference/sdk/flwip_port.md create mode 100644 bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_debug.c create mode 100644 bsp/phytium/libraries/standalone/drivers/media/Kconfig create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc.h rename bsp/phytium/libraries/standalone/{arch/armv8/aarch64/fpsci.h => drivers/media/fdcdp_lib/inc/fdc_common_hw.h} (51%) create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_hw.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_multi_display.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_param.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_aux.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_hw.h create mode 100644 bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_phy.h rename bsp/phytium/libraries/standalone/drivers/pcie/fpcie/{fpcir_intx.c => fpcie_intr.c} (64%) rename bsp/phytium/libraries/standalone/drivers/pcie/fpcie/{fpcir_intx.h => fpcie_intr.h} (82%) create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/Kconfig create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.h create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_g.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_hw.h rename bsp/phytium/libraries/standalone/{board/common/fsmp.h => drivers/scmi/fscmi_mhu/fmhu_intr.c} (54%) create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.h create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.h create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.h create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.c create mode 100644 bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.h create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcache.c create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.c create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.h create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fgeneric_timer.c rename bsp/phytium/libraries/standalone/{ => port}/arch/armv8/aarch32/fpsci.c (93%) rename bsp/phytium/libraries/standalone/{ => port}/arch/armv8/aarch32/fpsci.h (86%) create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsleep.c create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmc.h rename bsp/phytium/libraries/standalone/{arch/armv8/aarch32/gcc => port/arch/armv8/aarch32}/fsmccc_call.S (95%) create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/sdkopts.h create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.c create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.h rename bsp/phytium/libraries/standalone/{ => port}/arch/armv8/aarch64/farm_smccc.h (93%) create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fcache.c_x create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fgeneric_timer.c rename bsp/phytium/libraries/standalone/{ => port}/arch/armv8/aarch64/fpsci.c (75%) create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.h create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsleep.c rename bsp/phytium/libraries/standalone/{arch/armv8/aarch64/gcc => port/arch/armv8/aarch64}/fsmccc_call.S (91%) create mode 100644 bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/sdkopts.h create mode 100644 bsp/phytium/libraries/standalone/port/arch/fcache.h rename bsp/phytium/libraries/standalone/{arch/armv8/aarch32 => port/arch}/fgeneric_timer.h (54%) rename bsp/phytium/libraries/standalone/{common => port/arch}/fsleep.h (71%) create mode 100644 bsp/phytium/libraries/standalone/port/sdkconfig.h create mode 100644 bsp/phytium/tools/figures/commit_id.png create mode 100644 bsp/phytium/tools/figures/commit_reduce.png create mode 100644 bsp/phytium/tools/figures/rebase_commit.png create mode 100644 bsp/phytium/tools/figures/rebase_done.png create mode 100644 bsp/phytium/tools/figures/reduce_rtt.png create mode 100644 bsp/phytium/tools/lite_tools.md create mode 100644 bsp/phytium/tools/reduce_rtt_code.py diff --git a/bsp/phytium/.gitignore b/bsp/phytium/.gitignore index f577e88ffe..a93827b572 100644 --- a/bsp/phytium/.gitignore +++ b/bsp/phytium/.gitignore @@ -1 +1,11 @@ -*.dis \ No newline at end of file +*.dis +*.asm +/aarch32/tools/gnu_gcc/* +/aarch32/tools/ci.py +/aarch32/tools/get_toolchain.py +/aarch32/smart-env.sh +/aarch64/tools/gnu_gcc/* +/aarch64/tools/ci.py +/aarch64/tools/get_toolchain.py +/aarch64/smart-env.sh +**/**/makefile \ No newline at end of file diff --git a/bsp/phytium/aarch32/.config b/bsp/phytium/aarch32/.config index c85d79e0f9..e78d576898 100644 --- a/bsp/phytium/aarch32/.config +++ b/bsp/phytium/aarch32/.config @@ -6,12 +6,12 @@ # # RT-Thread Kernel # -CONFIG_RT_NAME_MAX=8 +CONFIG_RT_NAME_MAX=16 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set -# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMART=y CONFIG_RT_USING_SMP=y -CONFIG_RT_CPUS_NR=4 -CONFIG_RT_ALIGN_SIZE=8 +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y # CONFIG_RT_THREAD_PRIORITY_256 is not set @@ -22,11 +22,11 @@ CONFIG_RT_USING_HOOK=y CONFIG_RT_HOOK_USING_FUNC_PTR=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=256 -CONFIG_SYSTEM_THREAD_STACK_SIZE=256 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 CONFIG_RT_USING_TIMER_SOFT=y CONFIG_RT_TIMER_THREAD_PRIO=4 -CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 # # kservice optimization @@ -35,7 +35,7 @@ CONFIG_RT_KSERVICE_USING_STDLIB=y # CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set # CONFIG_RT_USING_TINY_FFS is not set -# CONFIG_RT_KPRINTF_USING_LONGLONG is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y CONFIG_RT_DEBUG=y # CONFIG_RT_DEBUG_COLOR is not set # CONFIG_RT_DEBUG_INIT_CONFIG is not set @@ -47,6 +47,7 @@ CONFIG_RT_DEBUG=y # CONFIG_RT_DEBUG_MEM_CONFIG is not set # CONFIG_RT_DEBUG_SLAB_CONFIG is not set # CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set # CONFIG_RT_DEBUG_MODULE_CONFIG is not set # @@ -66,7 +67,9 @@ CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMPOOL=y CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set -# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y # CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set # CONFIG_RT_USING_SLAB_AS_HEAP is not set @@ -84,9 +87,9 @@ CONFIG_RT_USING_DEVICE=y # CONFIG_RT_USING_DM is not set # CONFIG_RT_USING_INTERRUPT_INFO is not set CONFIG_RT_USING_CONSOLE=y -CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x50000 +CONFIG_RT_VER_NUM=0x50001 # CONFIG_RT_USING_STDC_ATOMIC is not set CONFIG_RT_USING_CACHE=y CONFIG_RT_USING_HW_ATOMIC=y @@ -96,6 +99,8 @@ CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_MM_MMU=y CONFIG_ARCH_ARM=y CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xc0000000 +# CONFIG_RT_IOREMAP_LATE is not set CONFIG_ARCH_ARM_CORTEX_A=y # CONFIG_RT_SMP_AUTO_BOOT is not set # CONFIG_RT_USING_GIC_V2 is not set @@ -108,7 +113,7 @@ CONFIG_RT_USING_GIC_V3=y # CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # CONFIG_RT_USING_LEGACY is not set CONFIG_RT_USING_MSH=y @@ -126,49 +131,70 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set CONFIG_DFS_FILESYSTEMS_MAX=4 CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 -CONFIG_DFS_FD_MAX=16 -# CONFIG_RT_USING_DFS_MNTTABLE is not set # CONFIG_RT_USING_DFS_ELMFAT is not set -# CONFIG_RT_USING_DFS_DEVFS is not set +CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set # CONFIG_RT_USING_DFS_CROMFS is not set -# CONFIG_RT_USING_DFS_RAMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y # CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_LWP_ENABLE_ASID=y +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_UNAMED_PIPE_NUMBER=64 -# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set CONFIG_RT_SERIAL_USING_DMA=y -CONFIG_RT_SERIAL_RB_BUFSZ=64 +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_HWTIMER is not set # CONFIG_RT_USING_CPUTIME is not set # CONFIG_RT_USING_I2C is not set # CONFIG_RT_USING_PHY is not set -CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_PIN is not set # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_DAC is not set -# CONFIG_RT_USING_NULL is not set -# CONFIG_RT_USING_ZERO is not set -# CONFIG_RT_USING_RANDOM is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_FDT is not set -# CONFIG_RT_USING_RTC is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set @@ -198,19 +224,28 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # POSIX (Portable Operating System Interface) layer # -# CONFIG_RT_USING_POSIX_FS is not set -# CONFIG_RT_USING_POSIX_DELAY is not set -# CONFIG_RT_USING_POSIX_CLOCK is not set -# CONFIG_RT_USING_POSIX_TIMER is not set +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y # CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_MODULE is not set # # Interprocess Communication (IPC) # -# CONFIG_RT_USING_POSIX_PIPE is not set -# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set -# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y # # Socket is in the 'Network' category @@ -228,9 +263,13 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # Utilities # -# CONFIG_RT_USING_RYM is not set +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_RT_USING_ULOG is not set -# CONFIG_RT_USING_UTEST is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 # CONFIG_RT_USING_VAR_EXPORT is not set CONFIG_RT_USING_ADT=y # CONFIG_RT_USING_RT_LINK is not set @@ -627,7 +666,6 @@ CONFIG_RT_USING_ADT=y # CONFIG_PKG_USING_LKDGUI is not set # CONFIG_PKG_USING_NRF5X_SDK is not set # CONFIG_PKG_USING_NRFX is not set -# CONFIG_PKG_USING_WM_LIBRARIES is not set # # Kendryte SDK @@ -685,7 +723,6 @@ CONFIG_RT_USING_ADT=y # CONFIG_PKG_USING_MISAKA_AT24CXX is not set # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set # CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set -# CONFIG_PKG_USING_BL_MCU_SDK is not set # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set # CONFIG_PKG_USING_RFM300 is not set @@ -1000,6 +1037,9 @@ CONFIG_RT_USING_ADT=y CONFIG_BSP_USING_UART=y CONFIG_RT_USING_UART1=y # CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set # # Board extended module Drivers @@ -1017,8 +1057,8 @@ CONFIG_USE_AARCH64_L1_TO_AARCH32=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -CONFIG_TARGET_E2000Q=y -# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -1055,6 +1095,8 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set # CONFIG_LOG_INFO is not set @@ -1065,4 +1107,5 @@ CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y # CONFIG_INTERRUPT_ROLE_SLAVE is not set # CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set # CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/.configs b/bsp/phytium/aarch32/.configs new file mode 100644 index 0000000000..149babc8c1 --- /dev/null +++ b/bsp/phytium/aarch32/.configs @@ -0,0 +1,1152 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xc0000000 +# CONFIG_RT_IOREMAP_LATE is not set +CONFIG_ARCH_ARM_CORTEX_A=y +# CONFIG_RT_SMP_AUTO_BOOT is not set +# CONFIG_RT_USING_GIC_V2 is not set +CONFIG_RT_USING_GIC_V3=y +# CONFIG_ARCH_ARM_SECURE_MODE is not set +# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_LWP_ENABLE_ASID=y +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +CONFIG_RT_USING_UTESTCASES=y + +# +# Utest Self Testcase +# +CONFIG_UTEST_SELF_PASS_TC=y + +# +# Kernel Testcase +# +CONFIG_UTEST_MEMHEAP_TC=y +CONFIG_UTEST_SMALL_MEM_TC=y +CONFIG_UTEST_IRQ_TC=y +CONFIG_UTEST_SEMAPHORE_TC=y +CONFIG_UTEST_EVENT_TC=y +CONFIG_UTEST_TIMER_TC=y +CONFIG_UTEST_MESSAGEQUEUE_TC=y +# CONFIG_UTEST_SIGNAL_TC is not set +CONFIG_UTEST_MUTEX_TC=y +CONFIG_UTEST_MAILBOX_TC=y +CONFIG_UTEST_THREAD_TC=y +CONFIG_UTEST_ATOMIC_TC=y + +# +# CPP11 Testcase +# +# CONFIG_UTEST_CPP11_THREAD_TC is not set + +# +# Utest Serial Testcase +# +# CONFIG_UTEST_SERIAL_TC is not set + +# +# RTT Posix Testcase +# +# CONFIG_RTT_POSIX_TESTCASE is not set + +# +# Memory Management Subsytem Testcase +# +# CONFIG_UTEST_MM_API_TC is not set +# CONFIG_UTEST_MM_LWP_TC is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_PHYTIUM_ARCH_AARCH32=y + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH32=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/Kconfig b/bsp/phytium/aarch32/Kconfig index 8293bc245d..cc9a3fe042 100644 --- a/bsp/phytium/aarch32/Kconfig +++ b/bsp/phytium/aarch32/Kconfig @@ -38,14 +38,14 @@ menu "Standalone Setting" config TARGET_ARMV8_AARCH32 bool "Armv8 Aarch32" default y - + config USE_AARCH64_L1_TO_AARCH32 bool prompt "Use Aarch64 L1 to Aarch32 code" default y help Use the Aarch64 to Aarch32 mode function - + source "$STANDALONE_DIR/board/Kconfig" source "$STANDALONE_DIR/drivers/Kconfig" source "$STANDALONE_DIR/common/Kconfig" diff --git a/bsp/phytium/aarch32/README.md b/bsp/phytium/aarch32/README.md index 7dcd689949..4c2e5944bd 100644 --- a/bsp/phytium/aarch32/README.md +++ b/bsp/phytium/aarch32/README.md @@ -1,18 +1,48 @@ - # AARCH32 工作模式使用 - 当开发者需要基于 Phytium 系列芯片进行开发时,可以从以下几个步骤出发配置芯片 +## 1. 准备编译环境 -## 1. 如何选择芯片 +- 在 aarch32 目录下创建 tools 目录,后续用于存放 RT-Thread 编译工具链 -- Windows Env 环境下 - -```shell - menuconfig +```sh +cd ./aarch32 +mkdir tools ``` -- Linux 环境下 +- 在 tools 目录下下载两个 python 脚本,get_toolchain.py 和 ci.py,下载完后给两个脚本添加执行权限 + +```shell +cd ./tools +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/tools/get_toolchain.py +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/tools/ci.py +chmod +x get_toolchain.py ci.py +``` + +- 然后运行 get_toolchain.py 脚本,拉取 aarch32 交叉编译链`arm-linux-musleabi_for_x86_64-pc-linux-gnu` + +```shell +python3 ./get_toolchain.py arm +``` + +> RT-Thread 5.0 后必须使用这个带 musl-libc 的编译链,不能使用`arm-none-eabi` + +- 在 aarch32 目录下下载脚本 smart-env.sh ,然后运行脚本生效环境变量 + +```shell +cd ./aarch32 +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/smart-env.sh +source ./smart-env.sh arm +``` + +- 如下所示是 aarch32 编译相关的环境变量,运行 scons 前要确保环境变量设置正确 + +![aarch32_env](./figures/aarch32_env.png) + +## 2. 如何选择芯片 + +- 以 E2000Q RT-Smart为例,Linux 环境下,运行 make load_e2000q_rtsmart 加载默认的 rtconfig, 然后输入下列命令,进入 menuconfig 进一步配置, ```shell scons --menuconfig @@ -27,8 +57,7 @@ Standalone Setting > Board Configuration > Chip ![](./figures/chip_select.png) ![](./figures/phytium_cpu_select.png) -## 2. 如何选择驱动 - +## 3. 如何选择驱动 ```shell scons --menuconfig @@ -42,9 +71,7 @@ Hardware Drivers > On-chip Peripheral Drivers ![](./figures/select_driver.png) - -## 3. 开启SDK中内部调试信息 - +## 4. 开启SDK中内部调试信息 ```shell scons --menuconfig @@ -55,8 +82,19 @@ Hardware Drivers > On-chip Peripheral Drivers ![](./figures/select_debug_info.png) +## 4. 如何切换至RT-Thread Smart 工作模式 -## 4. 编译程序 +```shell + + scons --menuconfig + +``` + +![1682477587050](figures/1682477587050.png) + +开发者通过以上配置开启RT-Thread Smart 功能 + +## 5. 编译程序 ```shell scons -c @@ -71,18 +109,36 @@ rtthread_a32.elf rtthread_a32.map ``` -## 5. 打包导出工程源代码 +## 6. 启动镜像程序 +- 可以用串口通过 XMODEM 协议将 bin/elf 文件上传到开发板,然后启动, + +- 首先在 Phytium 开发板上输入,上传 bin 文件 + +``` +loadx 80080000 +``` + +![](./figures/ymodem_upload.png) + +- 加载 bin 文件完成后,输入下列命令启动 + +``` +go 80080000 +``` + +## 7. 打包导出工程源代码 - 指定工程名和路径,打包RT-Thread内核和Phytium BSP代码,可以导出一个工程工程 + ``` python ./export_project.py -n=phytium-a32 -o=D:/proj/rt-thread-e2000/phytium-a32 ``` ![](./figures/export_project.png) +- 进入打包工程的目录,修改工程根目录 Kconfig 中的路径 BSP_DIR 和 STANDALONE_DIR -- 进入打包工程的目录,修改工程根目录 Kconfig 中的路径 BSP_DIR 和 STANDALONE_DIR > env 环境中的 menuconfig 不会调用 SConstruct 修改路径环境变量,因此需要手动修改路径 ``` @@ -99,10 +155,12 @@ config STANDALONE_DIR - 输入 menuconfig 和 scons 完成编译 +## 8. 将工程导入 RT-Studio -## 6. 将工程导入 RT-Studio - -- 在 RT-Studio 使用功能`RT-Thread Bsp 到工作空间`,导入 5. 中导出的 BSP 工程 +- 在 RT-Studio 使用功能 `RT-Thread Bsp 到工作空间`,导入 5. 中导出的 BSP 工程 - 设置 BSP 工程的交叉编译链后进行后续开发 -![](./figures/import_project.png) \ No newline at end of file +![](./figures/import_project.png) + +python get_toolchain.py arm +./smart-env.bat diff --git a/bsp/phytium/aarch32/SConstruct b/bsp/phytium/aarch32/SConstruct index 2d1eaf98f7..f0bd948838 100644 --- a/bsp/phytium/aarch32/SConstruct +++ b/bsp/phytium/aarch32/SConstruct @@ -53,6 +53,11 @@ if not IS_EXPORTED: # if project is not exported, libraries and board need to ma # include board objs.extend(SConscript(os.path.join(BSP_ROOT + '/board', 'SConscript'))) + +if GetDepend('RT_USING_SMART'): + # use smart link.lds + env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds') + # make a building DoBuilding(TARGET, objs) diff --git a/bsp/phytium/aarch32/applications/main.c b/bsp/phytium/aarch32/applications/main.c index e19779e113..5abc3130b0 100644 --- a/bsp/phytium/aarch32/applications/main.c +++ b/bsp/phytium/aarch32/applications/main.c @@ -70,7 +70,7 @@ void demo_core(void) int main(void) { #ifdef RT_USING_SMP - demo_core(); + // demo_core(); #endif return RT_EOK; } diff --git a/bsp/phytium/aarch32/applications/mnt.c b/bsp/phytium/aarch32/applications/mnt.c new file mode 100644 index 0000000000..447f518f78 --- /dev/null +++ b/bsp/phytium/aarch32/applications/mnt.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-04-27 huanghe first version + * + */ + +#include +#ifdef RT_USING_DFS_RAMFS +#include + +extern struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size); + +int mnt_init(void) +{ + rt_uint8_t *pool = RT_NULL; + rt_size_t size = 8*1024*1024; + + pool = rt_malloc(size); + if (pool == RT_NULL) + return 0; + + if (dfs_mount(RT_NULL, "/", "ram", 0, (const void *)dfs_ramfs_create(pool, size)) == 0) + rt_kprintf("RAM file system initializated!\n"); + else + rt_kprintf("RAM file system initializate failed!\n"); + + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif + +#ifdef BSP_USING_SDCARD_FATFS +#include +#include +#define DBG_TAG "app.filesystem" +#define DBG_LVL DBG_INFO +#include +static int filesystem_mount(void) +{ + while(rt_device_find("sd0") == RT_NULL) + { + rt_thread_mdelay(1); + } + + int ret = dfs_mount("sd0", "/", "elm", 0, 0); + if (ret != 0) + { + rt_kprintf("ret: %d\n",ret); + LOG_E("sd0 mount to '/' failed!"); + return ret; + } + + return RT_EOK; +} +INIT_ENV_EXPORT(filesystem_mount); +#endif diff --git a/bsp/phytium/aarch32/configs/e2000d_rtsmart b/bsp/phytium/aarch32/configs/e2000d_rtsmart new file mode 100644 index 0000000000..e78d576898 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000d_rtsmart @@ -0,0 +1,1111 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xc0000000 +# CONFIG_RT_IOREMAP_LATE is not set +CONFIG_ARCH_ARM_CORTEX_A=y +# CONFIG_RT_SMP_AUTO_BOOT is not set +# CONFIG_RT_USING_GIC_V2 is not set +CONFIG_RT_USING_GIC_V3=y +# CONFIG_ARCH_ARM_SECURE_MODE is not set +# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_LWP_ENABLE_ASID=y +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_PHYTIUM_ARCH_AARCH32=y + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH32=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/configs/e2000d_rtsmart.h b/bsp/phytium/aarch32/configs/e2000d_rtsmart.h new file mode 100644 index 0000000000..913e053bd7 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000d_rtsmart.h @@ -0,0 +1,319 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMART +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +#define SYSTEM_THREAD_STACK_SIZE 4096 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define RT_USING_CPU_FFS +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xc0000000 +#define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V3 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define LWP_ENABLE_ASID +#define RT_LWP_SHM_MAX_NR 64 + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_POLL +#define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 512 +#define RT_USING_POSIX_MESSAGE_QUEUE +#define RT_USING_POSIX_MESSAGE_SEMAPHORE + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define PHYTIUM_ARCH_AARCH32 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH32 +#define USE_AARCH64_L1_TO_AARCH32 + +/* Board Configuration */ + +#define TARGET_E2000D +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_GIC +#define ENABLE_GICV3 +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR +#define USE_DEFAULT_INTERRUPT_CONFIG +#define INTERRUPT_ROLE_MASTER + +#endif diff --git a/bsp/phytium/aarch32/configs/e2000d_rtthread b/bsp/phytium/aarch32/configs/e2000d_rtthread new file mode 100644 index 0000000000..9ccf9ae3b7 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000d_rtthread @@ -0,0 +1,1098 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_ARCH_ARM_CORTEX_A=y +# CONFIG_RT_SMP_AUTO_BOOT is not set +# CONFIG_RT_USING_GIC_V2 is not set +CONFIG_RT_USING_GIC_V3=y +# CONFIG_ARCH_ARM_SECURE_MODE is not set +# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_PHYTIUM_ARCH_AARCH32=y + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH32=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/configs/e2000d_rtthread.h b/bsp/phytium/aarch32/configs/e2000d_rtthread.h new file mode 100644 index 0000000000..9d6a4ca793 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000d_rtthread.h @@ -0,0 +1,308 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +#define SYSTEM_THREAD_STACK_SIZE 4096 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define RT_USING_CPU_FFS +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V3 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_POLL +#define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 512 +#define RT_USING_POSIX_MESSAGE_QUEUE +#define RT_USING_POSIX_MESSAGE_SEMAPHORE + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define PHYTIUM_ARCH_AARCH32 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH32 +#define USE_AARCH64_L1_TO_AARCH32 + +/* Board Configuration */ + +#define TARGET_E2000D +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_GIC +#define ENABLE_GICV3 +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR +#define USE_DEFAULT_INTERRUPT_CONFIG +#define INTERRUPT_ROLE_MASTER + +#endif diff --git a/bsp/phytium/aarch32/configs/e2000q_rtsmart b/bsp/phytium/aarch32/configs/e2000q_rtsmart new file mode 100644 index 0000000000..e844590ed2 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000q_rtsmart @@ -0,0 +1,1111 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=4 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xc0000000 +# CONFIG_RT_IOREMAP_LATE is not set +CONFIG_ARCH_ARM_CORTEX_A=y +# CONFIG_RT_SMP_AUTO_BOOT is not set +# CONFIG_RT_USING_GIC_V2 is not set +CONFIG_RT_USING_GIC_V3=y +# CONFIG_ARCH_ARM_SECURE_MODE is not set +# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_LWP_ENABLE_ASID=y +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_PHYTIUM_ARCH_AARCH32=y + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH32=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/configs/e2000q_rtsmart.h b/bsp/phytium/aarch32/configs/e2000q_rtsmart.h new file mode 100644 index 0000000000..3e169f917d --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000q_rtsmart.h @@ -0,0 +1,319 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMART +#define RT_USING_SMP +#define RT_CPUS_NR 4 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +#define SYSTEM_THREAD_STACK_SIZE 4096 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define RT_USING_CPU_FFS +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xc0000000 +#define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V3 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define LWP_ENABLE_ASID +#define RT_LWP_SHM_MAX_NR 64 + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_POLL +#define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 512 +#define RT_USING_POSIX_MESSAGE_QUEUE +#define RT_USING_POSIX_MESSAGE_SEMAPHORE + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define PHYTIUM_ARCH_AARCH32 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH32 +#define USE_AARCH64_L1_TO_AARCH32 + +/* Board Configuration */ + +#define TARGET_E2000Q +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_GIC +#define ENABLE_GICV3 +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR +#define USE_DEFAULT_INTERRUPT_CONFIG +#define INTERRUPT_ROLE_MASTER + +#endif diff --git a/bsp/phytium/aarch32/configs/e2000q_rtthread b/bsp/phytium/aarch32/configs/e2000q_rtthread new file mode 100644 index 0000000000..1ecf99a540 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000q_rtthread @@ -0,0 +1,1098 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=4 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_ARCH_ARM_CORTEX_A=y +# CONFIG_RT_SMP_AUTO_BOOT is not set +# CONFIG_RT_USING_GIC_V2 is not set +CONFIG_RT_USING_GIC_V3=y +# CONFIG_ARCH_ARM_SECURE_MODE is not set +# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=1024 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +CONFIG_RT_USING_POSIX_POLL=y +CONFIG_RT_USING_POSIX_SELECT=y +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=512 +CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y +CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_PHYTIUM_ARCH_AARCH32=y + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH32=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch32/configs/e2000q_rtthread.h b/bsp/phytium/aarch32/configs/e2000q_rtthread.h new file mode 100644 index 0000000000..39be678f07 --- /dev/null +++ b/bsp/phytium/aarch32/configs/e2000q_rtthread.h @@ -0,0 +1,308 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMP +#define RT_CPUS_NR 4 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +#define SYSTEM_THREAD_STACK_SIZE 4096 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define RT_USING_CPU_FFS +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V3 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_POLL +#define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 512 +#define RT_USING_POSIX_MESSAGE_QUEUE +#define RT_USING_POSIX_MESSAGE_SEMAPHORE + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define PHYTIUM_ARCH_AARCH32 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH32 +#define USE_AARCH64_L1_TO_AARCH32 + +/* Board Configuration */ + +#define TARGET_E2000Q +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_GIC +#define ENABLE_GICV3 +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR +#define USE_DEFAULT_INTERRUPT_CONFIG +#define INTERRUPT_ROLE_MASTER + +#endif diff --git a/bsp/phytium/aarch32/export_project.py b/bsp/phytium/aarch32/export_project.py index d28e6d7430..9b326e9f36 100644 --- a/bsp/phytium/aarch32/export_project.py +++ b/bsp/phytium/aarch32/export_project.py @@ -1,3 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2022, RT-Thread Development Team +# +# SPDX-License-Identifier: Apache-2.0 +# +# Email: opensource_embedded@phytium.com.cn +# +# +# Change Logs: +# Date Author Notes +# 2022-11-15 zhugengyu The first version +# + import os import shutil import argparse diff --git a/bsp/phytium/aarch32/figures/1682477587050.png b/bsp/phytium/aarch32/figures/1682477587050.png new file mode 100644 index 0000000000000000000000000000000000000000..b4cd94f336adb2376cf32f9f7d3bd7c30ecd88ae GIT binary patch literal 29723 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 literal 0 HcmV?d00001 diff --git a/bsp/phytium/aarch32/figures/ymodem_upload.png b/bsp/phytium/aarch32/figures/ymodem_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..9d166a09e832073cc23fccb2f3d25d6f5fd2d11e GIT binary patch literal 159452 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 z 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 &8RKZ!UO`{Z@MKL13eR|vEdj0*C`F~**mY!-S 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 rtthread_a32.asm + @$(OD) -S rtthread_a32.elf > rtthread_a32.dis + +all: + @echo "Build started..." + scons -j1024 + +clean: + @echo "Cleaning..." + scons -c + +menuconfig: + @echo "Running menuconfig..." + scons --menuconfig + +saveconfig: + @echo "Save configs to" ./configs/$(RTCONFIG) + @cp ./.config ./configs/$(RTCONFIG) -f + @cp ./rtconfig.h ./configs/$(RTCONFIG).h -f + +load_e2000q_rtsmart: + @echo "Load configs from ./configs/e2000q_rtsmart" + @cp ./configs/e2000q_rtsmart ./.config -f + @cp ./configs/e2000q_rtsmart.h ./rtconfig.h -f + @scons -c + +load_e2000q_rtthread: + @echo "Load configs from ./configs/e2000q_rtthread" + @cp ./configs/e2000q_rtthread ./.config -f + @cp ./configs/e2000q_rtthread.h ./rtconfig.h -f + @scons -c + +load_e2000d_rtsmart: + @echo "Load configs from ./configs/e2000d_rtsmart" + @cp ./configs/e2000d_rtsmart ./.config -f + @cp ./configs/e2000d_rtsmart.h ./rtconfig.h -f + @scons -c + +load_e2000d_rtthread: + @echo "Load configs from ./configs/e2000d_rtthread" + @cp ./configs/e2000d_rtthread ./.config -f + @cp ./configs/e2000d_rtthread.h ./rtconfig.h -f + scons -c \ No newline at end of file diff --git a/bsp/phytium/aarch32/rtconfig.h b/bsp/phytium/aarch32/rtconfig.h index b6e58d09ea..913e053bd7 100644 --- a/bsp/phytium/aarch32/rtconfig.h +++ b/bsp/phytium/aarch32/rtconfig.h @@ -6,10 +6,11 @@ /* RT-Thread Kernel */ -#define RT_NAME_MAX 8 +#define RT_NAME_MAX 16 +#define RT_USING_SMART #define RT_USING_SMP -#define RT_CPUS_NR 4 -#define RT_ALIGN_SIZE 8 +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 1000 @@ -18,15 +19,16 @@ #define RT_HOOK_USING_FUNC_PTR #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 256 -#define SYSTEM_THREAD_STACK_SIZE 256 +#define IDLE_THREAD_STACK_SIZE 4096 +#define SYSTEM_THREAD_STACK_SIZE 4096 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_THREAD_STACK_SIZE 4096 /* kservice optimization */ #define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG #define RT_DEBUG /* Inter-Thread communication */ @@ -42,6 +44,8 @@ #define RT_PAGE_MAX_ORDER 11 #define RT_USING_MEMPOOL #define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE #define RT_USING_SMALL_MEM_AS_HEAP #define RT_USING_HEAP @@ -49,15 +53,16 @@ #define RT_USING_DEVICE #define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart1" -#define RT_VER_NUM 0x50000 +#define RT_VER_NUM 0x50001 #define RT_USING_CACHE #define RT_USING_HW_ATOMIC #define RT_USING_CPU_FFS #define ARCH_MM_MMU #define ARCH_ARM #define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xc0000000 #define ARCH_ARM_CORTEX_A #define RT_USING_GIC_V3 @@ -65,7 +70,7 @@ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_STACK_SIZE 8192 #define RT_MAIN_THREAD_PRIORITY 10 #define RT_USING_MSH #define RT_USING_FINSH @@ -80,22 +85,43 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + #define RT_USING_DFS #define DFS_USING_POSIX #define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 #define DFS_FILESYSTEMS_MAX 4 #define DFS_FILESYSTEM_TYPES_MAX 4 -#define DFS_FD_MAX 16 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define LWP_ENABLE_ASID +#define RT_LWP_SHM_MAX_NR 64 /* Device Drivers */ #define RT_USING_DEVICE_IPC #define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_PIN +#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC /* Using USB */ @@ -106,9 +132,23 @@ /* POSIX (Portable Operating System Interface) layer */ +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_POLL +#define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER /* Interprocess Communication (IPC) */ +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 512 +#define RT_USING_POSIX_MESSAGE_QUEUE +#define RT_USING_POSIX_MESSAGE_SEMAPHORE /* Socket is in the 'Network' category */ @@ -118,6 +158,11 @@ /* Utilities */ +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 #define RT_USING_ADT /* RT-Thread Utestcases */ @@ -254,7 +299,7 @@ /* Board Configuration */ -#define TARGET_E2000Q +#define TARGET_E2000D #define TARGET_E2000 #define DEFAULT_DEBUG_PRINT_UART1 diff --git a/bsp/phytium/aarch32/rtconfig.py b/bsp/phytium/aarch32/rtconfig.py index a5202911db..507716031f 100644 --- a/bsp/phytium/aarch32/rtconfig.py +++ b/bsp/phytium/aarch32/rtconfig.py @@ -2,67 +2,53 @@ import os import rtconfig # toolchains options -ARCH='arm' -CPU='cortex-a' -CROSS_TOOL='gcc' - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = r'../../..' - -if os.getenv('RTT_CC'): - CROSS_TOOL = os.getenv('RTT_CC') - -# only support GNU GCC compiler. +ARCH ='arm' +CPU ='cortex-a' +CROSS_TOOL = 'gcc' PLATFORM = 'gcc' -EXEC_PATH = r'/usr/lib/arm-none-eabi/bin' -if os.getenv('AARCH32_CROSS_PATH'): - EXEC_PATH = os.getenv('AARCH32_CROSS_PATH') - print('EXEC_PATH = {}'.format(EXEC_PATH)) -else: - print('AARCH32_CROSS_PATH not found') +EXEC_PATH = os.getenv('RTT_EXEC_PATH') or r'/usr/bin' +BUILD = 'debug' -BUILD = 'debug' +LINK_SCRIPT = 'link.lds' -LIBPATH = EXEC_PATH + r'/../lib' if PLATFORM == 'gcc': - # toolchains - PREFIX = 'arm-none-eabi-' - CC = PREFIX + 'gcc' - CXX = PREFIX + 'g++' - AS = PREFIX + 'gcc' - AR = PREFIX + 'ar' - LINK = PREFIX + 'gcc' + PREFIX = os.getenv('RTT_CC_PREFIX') or 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' TARGET_EXT = 'elf' - SIZE = PREFIX + 'size' + SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' - OBJCPY = PREFIX + 'objcopy' - STRIP = PREFIX + 'strip' + OBJCPY = PREFIX + 'objcopy' + STRIP = PREFIX + 'strip' + CFPFLAGS = ' -msoft-float' + AFPFLAGS = ' -mfloat-abi=softfp -mfpu=neon' + DEVICE = ' -march=armv8-a -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' - DEVICE = ' -g -DGUEST -ffreestanding -Wextra -g -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -march=armv8-a -fdiagnostics-color=always' - - # CFLAGS = DEVICE + ' -Wall' - CFLAGS = DEVICE - AFLAGS = ' -c'+ DEVICE + ' -fsingle-precision-constant -fno-builtin -x assembler-with-cpp -D__ASSEMBLY__' - LINK_SCRIPT = 'link.lds' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_a32.map,-cref,-u,system_vectors'+\ - ' -T %s' % LINK_SCRIPT - - CPATH = '' - LPATH = LIBPATH - - # generate debug info in all cases - AFLAGS += ' -gdwarf-2' - CFLAGS += ' -g -gdwarf-2' + CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always' + CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -D_POSIX_SOURCE -fdiagnostics-color=always' + AFLAGS = DEVICE + ' -c' + AFPFLAGS + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_a32.map,-cref,-u,system_vectors -T '+ LINK_SCRIPT + ' -lsupc++ -lgcc -static' + CPATH = '' + LPATH = '' if BUILD == 'debug': - CFLAGS += ' -O0' + CFLAGS += ' -O0 -gdwarf-2' + CXXFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' else: - CFLAGS += ' -O2' + CFLAGS += ' -Os' + CXXFLAGS += ' -Os' + CXXFLAGS += ' -Woverloaded-virtual -fno-rtti' - CXXFLAGS = CFLAGS + M_CFLAGS = CFLAGS + ' -mlong-calls -fPIC ' + M_CXXFLAGS = CXXFLAGS + ' -mlong-calls -fPIC' + M_LFLAGS = DEVICE + CXXFLAGS + ' -Wl,--gc-sections,-z,max-page-size=0x4' +\ + ' -shared -fPIC -nostartfiles -nostdlib -static-libgcc' + M_POST_ACTION = STRIP + ' -R .hash $TARGET\n' + SIZE + ' $TARGET \n' - POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_a32.bin\n' +\ - SIZE + ' $TARGET \n' + DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread_a32.asm\n' + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_a32.bin\n' + SIZE + ' $TARGET \n' diff --git a/bsp/phytium/aarch32/sdkconfig.h b/bsp/phytium/aarch32/sdkconfig.h deleted file mode 100644 index 8913e55fd9..0000000000 --- a/bsp/phytium/aarch32/sdkconfig.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: sdkconfig.h - * Date: 2022-10-13 15:53:46 - * LastEditTime: 2022-10-13 15:53:46 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#ifndef SDK_CONFIG_H__ -#define SDK_CONFIG_H__ - -#include "rtconfig.h" - - -/* arch */ - -#if defined(TARGET_ARMV8_AARCH32) - #define CONFIG_TARGET_ARMV8_AARCH32 -#endif - -#if defined(USE_AARCH64_L1_TO_AARCH32) - #define CONFIG_USE_AARCH64_L1_TO_AARCH32 -#endif - -/* board */ - -/* E2000 */ - -#if defined(TARGET_E2000) - #define CONFIG_TARGET_E2000 -#endif - - -/* debug */ - -#ifdef LOG_VERBOS - #define CONFIG_LOG_VERBOS -#endif - -#ifdef LOG_ERROR - #define CONFIG_LOG_ERROR -#endif - -#ifdef LOG_WARN - #define CONFIG_LOG_WARN -#endif - -#ifdef LOG_INFO - #define CONFIG_LOG_INFO -#endif - -#ifdef LOG_DEBUG - #define CONFIG_LOG_DEBUG -#endif - -#ifdef BOOTUP_DEBUG_PRINTS - #define CONFIG_BOOTUP_DEBUG_PRINTS -#endif - -#endif diff --git a/bsp/phytium/aarch64/.config b/bsp/phytium/aarch64/.config index 400a6c38f3..c63a196b1f 100644 --- a/bsp/phytium/aarch64/.config +++ b/bsp/phytium/aarch64/.config @@ -10,20 +10,20 @@ CONFIG_RT_NAME_MAX=16 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMART is not set CONFIG_RT_USING_SMP=y -CONFIG_RT_CPUS_NR=4 -CONFIG_RT_ALIGN_SIZE=8 +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y # CONFIG_RT_THREAD_PRIORITY_256 is not set CONFIG_RT_THREAD_PRIORITY_MAX=32 -CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_TICK_PER_SECOND=1000 CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_HOOK_USING_FUNC_PTR=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=4096 -CONFIG_SYSTEM_THREAD_STACK_SIZE=4096 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_SYSTEM_THREAD_STACK_SIZE=40960 CONFIG_RT_USING_TIMER_SOFT=y CONFIG_RT_TIMER_THREAD_PRIO=4 CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 @@ -47,6 +47,7 @@ CONFIG_RT_DEBUG=y # CONFIG_RT_DEBUG_MEM_CONFIG is not set # CONFIG_RT_DEBUG_SLAB_CONFIG is not set # CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_PAGE_LEAK is not set # CONFIG_RT_DEBUG_MODULE_CONFIG is not set # @@ -66,7 +67,9 @@ CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMPOOL=y CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set -# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y # CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set # CONFIG_RT_USING_SLAB_AS_HEAP is not set @@ -86,12 +89,12 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x50000 +CONFIG_RT_VER_NUM=0x50001 # CONFIG_RT_USING_STDC_ATOMIC is not set CONFIG_ARCH_CPU_64BIT=y CONFIG_RT_USING_CACHE=y CONFIG_RT_USING_HW_ATOMIC=y -# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # CONFIG_RT_USING_CPU_FFS is not set CONFIG_ARCH_MM_MMU=y @@ -104,7 +107,7 @@ CONFIG_ARCH_ARMV8=y # CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=4096 +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # CONFIG_RT_USING_LEGACY is not set CONFIG_RT_USING_MSH=y @@ -122,18 +125,24 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set CONFIG_DFS_FILESYSTEMS_MAX=4 CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 -CONFIG_DFS_FD_MAX=16 -# CONFIG_RT_USING_DFS_MNTTABLE is not set # CONFIG_RT_USING_DFS_ELMFAT is not set -# CONFIG_RT_USING_DFS_DEVFS is not set +CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set # CONFIG_RT_USING_DFS_CROMFS is not set -# CONFIG_RT_USING_DFS_RAMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y # CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_FAL is not set @@ -155,18 +164,20 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CPUTIME is not set # CONFIG_RT_USING_I2C is not set # CONFIG_RT_USING_PHY is not set -CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_PIN is not set # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_DAC is not set -# CONFIG_RT_USING_NULL is not set -# CONFIG_RT_USING_ZERO is not set -# CONFIG_RT_USING_RANDOM is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_FDT is not set -# CONFIG_RT_USING_RTC is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set @@ -196,10 +207,18 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # POSIX (Portable Operating System Interface) layer # -# CONFIG_RT_USING_POSIX_FS is not set -# CONFIG_RT_USING_POSIX_DELAY is not set -# CONFIG_RT_USING_POSIX_CLOCK is not set -# CONFIG_RT_USING_POSIX_TIMER is not set +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y # CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_MODULE is not set @@ -226,7 +245,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # Utilities # -# CONFIG_RT_USING_RYM is not set +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set @@ -624,7 +645,6 @@ CONFIG_RT_USING_ADT=y # CONFIG_PKG_USING_LKDGUI is not set # CONFIG_PKG_USING_NRF5X_SDK is not set # CONFIG_PKG_USING_NRFX is not set -# CONFIG_PKG_USING_WM_LIBRARIES is not set # # Kendryte SDK @@ -682,7 +702,6 @@ CONFIG_RT_USING_ADT=y # CONFIG_PKG_USING_MISAKA_AT24CXX is not set # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set # CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set -# CONFIG_PKG_USING_BL_MCU_SDK is not set # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set # CONFIG_PKG_USING_RFM300 is not set @@ -721,7 +740,31 @@ CONFIG_RT_USING_ADT=y # # samples: kernel and components samples # -# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set # CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set # CONFIG_PKG_USING_NETWORK_SAMPLES is not set # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set @@ -997,6 +1040,9 @@ CONFIG_RT_USING_ADT=y CONFIG_BSP_USING_UART=y CONFIG_RT_USING_UART1=y # CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set # # Board extended module Drivers @@ -1004,6 +1050,7 @@ CONFIG_RT_USING_UART1=y CONFIG_BSP_USING_GIC=y CONFIG_BSP_USING_GICV3=y CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=0 # # Standalone Setting @@ -1015,8 +1062,8 @@ CONFIG_TARGET_ARMV8_AARCH64=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -CONFIG_TARGET_E2000Q=y -# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -1026,8 +1073,14 @@ CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # # Components Configuration # -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y # CONFIG_USE_GIC is not set CONFIG_USE_SERIAL=y @@ -1052,6 +1105,8 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set # CONFIG_LOG_INFO is not set @@ -1060,4 +1115,5 @@ CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set # CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set # CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/.configs b/bsp/phytium/aarch64/.configs new file mode 100644 index 0000000000..c1497e82e5 --- /dev/null +++ b/bsp/phytium/aarch64/.configs @@ -0,0 +1,1116 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y +CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=0 + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH64=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y +# CONFIG_USE_GIC is not set +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +# CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/Kconfig b/bsp/phytium/aarch64/Kconfig index 973bc46fe1..25f6b180c3 100644 --- a/bsp/phytium/aarch64/Kconfig +++ b/bsp/phytium/aarch64/Kconfig @@ -38,7 +38,21 @@ config PHYTIUM_ARCH_AARCH64 select RT_USING_USER_MAIN select ARCH_CPU_64BIT select TARGET_ARMV8_AARCH64 + select ARCH_ARM_BOOTWITH_FLUSH_CACHE default y + + +if TARGET_E2000Q + config ARM_SPI_BIND_CPU_ID + int + default 2 +endif + +if TARGET_E2000D + config ARM_SPI_BIND_CPU_ID + int + default 0 +endif menu "Standalone Setting" config TARGET_ARMV8_AARCH64 diff --git a/bsp/phytium/aarch64/README.md b/bsp/phytium/aarch64/README.md index 8ca947b5d8..94dace980d 100644 --- a/bsp/phytium/aarch64/README.md +++ b/bsp/phytium/aarch64/README.md @@ -1,31 +1,52 @@ - - # AARCH64 工作模式使用 - 当开发者需要基于 Phytium 系列芯片进行开发时,可以从以下几个步骤出发配置芯片 -## 1. 如何选择芯片 +## 1. 准备编译环境 + +- 在 aarch64 目录下创建 tools 目录,后续用于存放 RT-Thread 编译工具链 + +```sh +cd ./aarch64 +mkdir tools +``` + +- 在 tools 目录下下载两个 python 脚本,get_toolchain.py 和 ci.py,下载完后给两个脚本添加执行权限 + +```shell +cd ./tools +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/tools/get_toolchain.py +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/tools/ci.py +chmod +x get_toolchain.py ci.py +``` + +- 然后运行 get_toolchain.py 脚本,拉取 aarch64 交叉编译链`aarch64-linux-musleabi_for_x86_64-pc-linux-gnu` + +```shell +python3 ./get_toolchain.py aarch64 +``` + +> RT-Thread 5.0 后必须使用这个带 musl-libc 的编译链,不能使用`aarch64-none-elf` + +- 在 aarch64 目录下下载脚本 smart_env.sh ,然后运行脚本生效环境变量 + +```shell +cd ./aarch64 +wget https://gitee.com/rtthread/ART-Pi-smart/raw/master/smart-env.sh +source ./smart-env.sh aarch64 +``` + +- 如下所示是 aarch64 编译相关的环境变量,运行 scons 前要确保环境变量设置正确 + +![aarch64_env](./figures/aarch64_env.png) + +## NOTE + +- 请使用ubuntu20.04 开发环境进行上述操作,其他开发环境没有进行测试 + +## 2. 如何选择芯片 + +- 以 E2000Q RT-Smart为例,Linux 环境下,运行 make load_e2000q_rtsmart 加载默认的 rtconfig, 然后输入下列命令,进入 menuconfig 进一步配置, ```shell scons --menuconfig @@ -40,8 +61,7 @@ Standalone Setting > Board Configuration > Chip ![](./figures/chip_select.png) ![](./figures/phytium_cpu_select.png) -## 2. 如何选择驱动 - +## 3. 如何选择驱动 ```shell scons --menuconfig @@ -55,9 +75,17 @@ Hardware Drivers Config > On-chip Peripheral Drivers ![](./figures/select_driver.png) +## 4. 如何切换至RT-Thread Smart 工作模式 -## 3. 开启SDK中内部调试信息 +```shell + scons --menuconfig +``` +![1682474861110](./figures/1682474861110.png) + +开发者通过以上配置开启RT-Thread Smart 功能 + +## 5. 开启SDK中内部调试信息 ```shell scons --menuconfig @@ -67,9 +95,7 @@ Hardware Drivers Config > On-chip Peripheral Drivers ![](./figures/select_debug_info.png) - - -## 4. 编译程序 +## 6. 编译程序 ```shell scons -c @@ -84,18 +110,38 @@ rtthread_a64.elf rtthread_a64.map ``` -## 5. 打包导出工程源代码 +## 7. 启动镜像程序 +- 可以用串口通过 XMODEM 协议将 bin/elf 文件上传到开发板,然后启动, + +- 首先在 Phytium 开发板上输入,上传 bin 文件 + +``` +loadx 80080000 +``` + +![](./figures/ymodem_upload.png) + +- 加载 bin 文件完成后,输入下列命令启动 + +``` +go 80080000 +``` + +> RT-Smart 模式下,64 位不能用 bootelf 启动 elf 文件 + +## 8. 打包导出工程源代码 - 指定工程名和路径,打包RT-Thread内核和Phytium BSP代码,可以导出一个工程工程 + ``` python ./export_project.py -n=phytium-a64 -o=D:/proj/rt-thread-e2000/phytium-a64 ``` ![](./figures/export_project.png) +- 进入打包工程的目录,修改工程根目录 Kconfig 中的路径 BSP_DIR 和 STANDALONE_DIR -- 进入打包工程的目录,修改工程根目录 Kconfig 中的路径 BSP_DIR 和 STANDALONE_DIR > env 环境中的 menuconfig 不会调用 SConstruct 修改路径环境变量,因此需要手动修改路径 ``` @@ -112,10 +158,9 @@ config STANDALONE_DIR - 输入 menuconfig 和 scons 完成编译 +## 9. 将工程导入 RT-Studio -## 6. 将工程导入 RT-Studio - -- 在 RT-Studio 使用功能`RT-Thread Bsp 到工作空间`,导入 5. 中导出的 BSP 工程 +- 在 RT-Studio 使用功能 `RT-Thread Bsp 到工作空间`,导入 5. 中导出的 BSP 工程 - 设置 BSP 工程的交叉编译链后进行后续开发 -![](./figures/import_project.png) \ No newline at end of file +![](./figures/import_project.png) diff --git a/bsp/phytium/aarch64/SConstruct b/bsp/phytium/aarch64/SConstruct index ae659dfb21..8132cd8def 100644 --- a/bsp/phytium/aarch64/SConstruct +++ b/bsp/phytium/aarch64/SConstruct @@ -53,6 +53,10 @@ if not IS_EXPORTED: # if project is not exported, libraries and board need to ma # include board objs.extend(SConscript(os.path.join(BSP_ROOT + '/board', 'SConscript'))) +if GetDepend('RT_USING_SMART'): + # use smart link.lds + env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds') + # make a building DoBuilding(TARGET, objs) diff --git a/bsp/phytium/aarch64/applications/SConscript b/bsp/phytium/aarch64/applications/SConscript index 5206463fe9..01eb940dfb 100644 --- a/bsp/phytium/aarch64/applications/SConscript +++ b/bsp/phytium/aarch64/applications/SConscript @@ -3,7 +3,7 @@ Import('rtconfig') from building import * cwd = os.path.join(str(Dir('#')), 'applications') -src = Glob('*.c') +src = Glob('*.c') CPPPATH = [cwd, str(Dir('#'))] group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/phytium/aarch64/applications/main.c b/bsp/phytium/aarch64/applications/main.c index 96c5ad2dc0..24379b50c0 100644 --- a/bsp/phytium/aarch64/applications/main.c +++ b/bsp/phytium/aarch64/applications/main.c @@ -30,7 +30,7 @@ static char *core_thread_name[8] = "core6_test", "core7_test" }; -static rt_uint8_t core_stack[RT_CPUS_NR][1024]; +static rt_uint8_t core_stack[RT_CPUS_NR][4096]; static void demo_core_thread(void *parameter) { @@ -41,7 +41,7 @@ static void demo_core_thread(void *parameter) level = rt_cpus_lock(); rt_kprintf("Hi, core%d \r\n", rt_hw_cpu_id()); rt_cpus_unlock(level); - rt_thread_mdelay(2000000); + rt_thread_mdelay(200000); } } @@ -57,7 +57,7 @@ void demo_core(void) demo_core_thread, RT_NULL, &core_stack[i], - 1024, + 4096, 20, 32); diff --git a/bsp/phytium/aarch64/applications/mnt.c b/bsp/phytium/aarch64/applications/mnt.c new file mode 100644 index 0000000000..447f518f78 --- /dev/null +++ b/bsp/phytium/aarch64/applications/mnt.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-04-27 huanghe first version + * + */ + +#include +#ifdef RT_USING_DFS_RAMFS +#include + +extern struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size); + +int mnt_init(void) +{ + rt_uint8_t *pool = RT_NULL; + rt_size_t size = 8*1024*1024; + + pool = rt_malloc(size); + if (pool == RT_NULL) + return 0; + + if (dfs_mount(RT_NULL, "/", "ram", 0, (const void *)dfs_ramfs_create(pool, size)) == 0) + rt_kprintf("RAM file system initializated!\n"); + else + rt_kprintf("RAM file system initializate failed!\n"); + + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif + +#ifdef BSP_USING_SDCARD_FATFS +#include +#include +#define DBG_TAG "app.filesystem" +#define DBG_LVL DBG_INFO +#include +static int filesystem_mount(void) +{ + while(rt_device_find("sd0") == RT_NULL) + { + rt_thread_mdelay(1); + } + + int ret = dfs_mount("sd0", "/", "elm", 0, 0); + if (ret != 0) + { + rt_kprintf("ret: %d\n",ret); + LOG_E("sd0 mount to '/' failed!"); + return ret; + } + + return RT_EOK; +} +INIT_ENV_EXPORT(filesystem_mount); +#endif diff --git a/bsp/phytium/aarch64/configs/e2000d_rtsmart b/bsp/phytium/aarch64/configs/e2000d_rtsmart new file mode 100644 index 0000000000..d938d301ea --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000d_rtsmart @@ -0,0 +1,1129 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_SYSTEM_THREAD_STACK_SIZE=40960 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xffff000000000000 +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y +CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=0 + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH64=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y +# CONFIG_USE_GIC is not set +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +# CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/configs/e2000d_rtsmart.h b/bsp/phytium/aarch64/configs/e2000d_rtsmart.h new file mode 100644 index 0000000000..d20b661fbb --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000d_rtsmart.h @@ -0,0 +1,316 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMART +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 40960 +#define SYSTEM_THREAD_STACK_SIZE 40960 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define ARCH_ARM_BOOTWITH_FLUSH_CACHE +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xffff000000000000 +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define RT_LWP_SHM_MAX_NR 64 + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + +#define PKG_USING_KERNEL_SAMPLES +#define PKG_USING_KERNEL_SAMPLES_LATEST_VERSION +#define PKG_USING_KERNEL_SAMPLES_EN + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define BSP_USING_GIC +#define BSP_USING_GICV3 +#define PHYTIUM_ARCH_AARCH64 +#define ARM_SPI_BIND_CPU_ID 0 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH64 + +/* Board Configuration */ + +#define TARGET_E2000D +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_SPI +#define USE_FSPIM +#define USE_QSPI + +/* Qspi Configuration */ + +#define USE_FQSPI +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR + +#endif diff --git a/bsp/phytium/aarch64/configs/e2000d_rtthread b/bsp/phytium/aarch64/configs/e2000d_rtthread new file mode 100644 index 0000000000..b228d85dfc --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000d_rtthread @@ -0,0 +1,1118 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_SYSTEM_THREAD_STACK_SIZE=40960 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y +CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=0 + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH64=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y +# CONFIG_USE_GIC is not set +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +# CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/configs/e2000d_rtthread.h b/bsp/phytium/aarch64/configs/e2000d_rtthread.h new file mode 100644 index 0000000000..76b14cfc28 --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000d_rtthread.h @@ -0,0 +1,306 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 40960 +#define SYSTEM_THREAD_STACK_SIZE 40960 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define ARCH_ARM_BOOTWITH_FLUSH_CACHE +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + +#define PKG_USING_KERNEL_SAMPLES +#define PKG_USING_KERNEL_SAMPLES_LATEST_VERSION +#define PKG_USING_KERNEL_SAMPLES_EN + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define BSP_USING_GIC +#define BSP_USING_GICV3 +#define PHYTIUM_ARCH_AARCH64 +#define ARM_SPI_BIND_CPU_ID 0 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH64 + +/* Board Configuration */ + +#define TARGET_E2000D +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_SPI +#define USE_FSPIM +#define USE_QSPI + +/* Qspi Configuration */ + +#define USE_FQSPI +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR + +#endif diff --git a/bsp/phytium/aarch64/configs/e2000q_rtsmart b/bsp/phytium/aarch64/configs/e2000q_rtsmart new file mode 100644 index 0000000000..de04313cc9 --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000q_rtsmart @@ -0,0 +1,1129 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=4 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_SYSTEM_THREAD_STACK_SIZE=40960 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xffff000000000000 +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y +CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=2 + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH64=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y +# CONFIG_USE_GIC is not set +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +# CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/configs/e2000q_rtsmart.h b/bsp/phytium/aarch64/configs/e2000q_rtsmart.h new file mode 100644 index 0000000000..7b4988e9a1 --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000q_rtsmart.h @@ -0,0 +1,316 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMART +#define RT_USING_SMP +#define RT_CPUS_NR 4 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 40960 +#define SYSTEM_THREAD_STACK_SIZE 40960 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define ARCH_ARM_BOOTWITH_FLUSH_CACHE +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xffff000000000000 +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define RT_LWP_SHM_MAX_NR 64 + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + +#define PKG_USING_KERNEL_SAMPLES +#define PKG_USING_KERNEL_SAMPLES_LATEST_VERSION +#define PKG_USING_KERNEL_SAMPLES_EN + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define BSP_USING_GIC +#define BSP_USING_GICV3 +#define PHYTIUM_ARCH_AARCH64 +#define ARM_SPI_BIND_CPU_ID 2 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH64 + +/* Board Configuration */ + +#define TARGET_E2000Q +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_SPI +#define USE_FSPIM +#define USE_QSPI + +/* Qspi Configuration */ + +#define USE_FQSPI +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR + +#endif diff --git a/bsp/phytium/aarch64/configs/e2000q_rtthread b/bsp/phytium/aarch64/configs/e2000q_rtthread new file mode 100644 index 0000000000..8edc0d37f3 --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000q_rtthread @@ -0,0 +1,1118 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=4 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=40960 +CONFIG_SYSTEM_THREAD_STACK_SIZE=40960 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +CONFIG_RT_KSERVICE_USING_STDLIB=y +# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +CONFIG_RT_KPRINTF_USING_LONGLONG=y +CONFIG_RT_DEBUG=y +# CONFIG_RT_DEBUG_COLOR is not set +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_PAGE_MAX_ORDER=11 +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BEST_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +CONFIG_RT_USING_HW_ATOMIC=y +CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_MM_MMU=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PIN is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +CONFIG_RT_USING_POSIX_FS=y +CONFIG_RT_USING_POSIX_DEVIO=y +CONFIG_RT_USING_POSIX_STDIO=y +# CONFIG_RT_USING_POSIX_POLL is not set +# CONFIG_RT_USING_POSIX_SELECT is not set +# CONFIG_RT_USING_POSIX_SOCKET is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +CONFIG_RT_USING_POSIX_TIMER=y +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +CONFIG_RT_USING_RYM=y +# CONFIG_YMODEM_USING_CRC_TABLE is not set +CONFIG_YMODEM_USING_FILE_TRANSFER=y +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_ADT=y +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_FINGERPRINT is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +CONFIG_PKG_USING_KERNEL_SAMPLES=y +CONFIG_PKG_KERNEL_SAMPLES_PATH="/packages/misc/samples/kernel_samples" +# CONFIG_PKG_USING_KERNEL_SAMPLES_V030 is not set +# CONFIG_PKG_USING_KERNEL_SAMPLES_V040 is not set +CONFIG_PKG_USING_KERNEL_SAMPLES_LATEST_VERSION=y +CONFIG_PKG_KERNEL_SAMPLES_VER="latest" +CONFIG_PKG_USING_KERNEL_SAMPLES_EN=y +# CONFIG_PKG_USING_KERNEL_SAMPLES_ZH is not set +# CONFIG_KERNEL_SAMPLES_USING_THREAD is not set +# CONFIG_KERNEL_SAMPLES_USING_SEMAPHORE is not set +# CONFIG_KERNEL_SAMPLES_USING_MUTEX is not set +# CONFIG_KERNEL_SAMPLES_USING_MAILBOX is not set +# CONFIG_KERNEL_SAMPLES_USING_EVENT is not set +# CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE is not set +# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set +# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set +# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set +# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set +# CONFIG_KERNEL_SAMPLES_USING_INTERRUPT is not set +# CONFIG_KERNEL_SAMPLES_USING_PRI_INVERSION is not set +# CONFIG_KERNEL_SAMPLES_USING_TIME_SLICE is not set +# CONFIG_KERNEL_SAMPLES_USING_SCHEDULER_HOOK is not set +# CONFIG_KERNEL_SAMPLES_USING_PRODUCER_CONSUMER is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# + +# +# Hardware Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_RT_USING_UART1=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CAN is not set +# CONFIG_BSP_USING_QSPI is not set + +# +# Board extended module Drivers +# +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y +CONFIG_PHYTIUM_ARCH_AARCH64=y +CONFIG_ARM_SPI_BIND_CPU_ID=2 + +# +# Standalone Setting +# +CONFIG_TARGET_ARMV8_AARCH64=y + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set + +# +# Components Configuration +# +CONFIG_USE_SPI=y +CONFIG_USE_FSPIM=y +CONFIG_USE_QSPI=y + +# +# Qspi Configuration +# +CONFIG_USE_FQSPI=y +# CONFIG_USE_GIC is not set +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# CONFIG_USE_SCMI_MHU is not set +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +# CONFIG_USE_DEFAULT_INTERRUPT_CONFIG is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_LOG_DISPALY_CORE_NUM is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set diff --git a/bsp/phytium/aarch64/configs/e2000q_rtthread.h b/bsp/phytium/aarch64/configs/e2000q_rtthread.h new file mode 100644 index 0000000000..556c088f1f --- /dev/null +++ b/bsp/phytium/aarch64/configs/e2000q_rtthread.h @@ -0,0 +1,306 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_USING_SMP +#define RT_CPUS_NR 4 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 40960 +#define SYSTEM_THREAD_STACK_SIZE 40960 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_KSERVICE_USING_STDLIB +#define RT_KPRINTF_USING_LONGLONG +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x50001 +#define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define RT_USING_HW_ATOMIC +#define ARCH_ARM_BOOTWITH_FLUSH_CACHE +#define ARCH_MM_MMU +#define ARCH_ARM +#define ARCH_ARM_MMU +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER +#define RT_USING_ADT + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + +/* sensors drivers */ + + +/* touch drivers */ + + +/* Kendryte SDK */ + + +/* AI packages */ + + +/* Signal Processing and Control Algorithm Packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + +#define PKG_USING_KERNEL_SAMPLES +#define PKG_USING_KERNEL_SAMPLES_LATEST_VERSION +#define PKG_USING_KERNEL_SAMPLES_EN + +/* entertainment: terminal games and other interesting software packages */ + + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + + +/* Signal IO */ + + +/* Uncategorized */ + +/* Hardware Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define RT_USING_UART1 + +/* Board extended module Drivers */ + +#define BSP_USING_GIC +#define BSP_USING_GICV3 +#define PHYTIUM_ARCH_AARCH64 +#define ARM_SPI_BIND_CPU_ID 2 + +/* Standalone Setting */ + +#define TARGET_ARMV8_AARCH64 + +/* Board Configuration */ + +#define TARGET_E2000Q +#define TARGET_E2000 +#define DEFAULT_DEBUG_PRINT_UART1 + +/* Components Configuration */ + +#define USE_SPI +#define USE_FSPIM +#define USE_QSPI + +/* Qspi Configuration */ + +#define USE_FQSPI +#define USE_SERIAL + +/* Usart Configuration */ + +#define ENABLE_Pl011_UART +#define LOG_ERROR + +#endif diff --git a/bsp/phytium/aarch64/export_project.py b/bsp/phytium/aarch64/export_project.py index d4c690c7cb..700c60b173 100644 --- a/bsp/phytium/aarch64/export_project.py +++ b/bsp/phytium/aarch64/export_project.py @@ -1,3 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2022, RT-Thread Development Team +# +# SPDX-License-Identifier: Apache-2.0 +# +# Email: opensource_embedded@phytium.com.cn +# +# +# Change Logs: +# Date Author Notes +# 2022-11-15 zhugengyu The first version +# + import os import shutil import argparse diff --git a/bsp/phytium/aarch64/figures/1682474861110.png b/bsp/phytium/aarch64/figures/1682474861110.png new file mode 100644 index 0000000000000000000000000000000000000000..b42699bde85ace240173019055a4f0d36297c79f GIT binary patch literal 29196 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 P`p+HtyRi4N4+8!Rr#C6~ literal 0 HcmV?d00001 diff --git a/bsp/phytium/aarch64/figures/aarch64_env.png b/bsp/phytium/aarch64/figures/aarch64_env.png new file mode 100644 index 0000000000000000000000000000000000000000..73010c82d3b5e874233fa8b8c8d9c17cdc0e924a GIT binary patch literal 11983 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 rtthread_a64.asm + @$(OD) -S rtthread_a64.elf > rtthread_a64.dis + +all: + @echo "Build started..." + scons -j1024 + +clean: + @echo "Cleaning..." + scons -c + +menuconfig: + @echo "Running menuconfig..." + scons --menuconfig + +saveconfig: + @echo "Save configs to" ./configs/$(RTCONFIG) + @cp ./.config ./configs/$(RTCONFIG) -f + @cp ./rtconfig.h ./configs/$(RTCONFIG).h -f + +load_e2000q_rtsmart: + @echo "Load configs from ./configs/e2000q_rtsmart" + @cp ./configs/e2000q_rtsmart ./.config -f + @cp ./configs/e2000q_rtsmart.h ./rtconfig.h -f + @scons -c + +load_e2000q_rtthread: + @echo "Load configs from ./configs/e2000q_rtthread" + @cp ./configs/e2000q_rtthread ./.config -f + @cp ./configs/e2000q_rtthread.h ./rtconfig.h -f + @scons -c + +load_e2000d_rtsmart: + @echo "Load configs from ./configs/e2000d_rtsmart" + @cp ./configs/e2000d_rtsmart ./.config -f + @cp ./configs/e2000d_rtsmart.h ./rtconfig.h -f + @scons -c + +load_e2000d_rtthread: + @echo "Load configs from ./configs/e2000d_rtthread" + @cp ./configs/e2000d_rtthread ./.config -f + @cp ./configs/e2000d_rtthread.h ./rtconfig.h -f + @scons -c diff --git a/bsp/phytium/aarch64/rtconfig.h b/bsp/phytium/aarch64/rtconfig.h index 1a5d523b5b..76b14cfc28 100644 --- a/bsp/phytium/aarch64/rtconfig.h +++ b/bsp/phytium/aarch64/rtconfig.h @@ -8,18 +8,18 @@ #define RT_NAME_MAX 16 #define RT_USING_SMP -#define RT_CPUS_NR 4 -#define RT_ALIGN_SIZE 8 +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 +#define RT_TICK_PER_SECOND 1000 #define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK #define RT_HOOK_USING_FUNC_PTR #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 4096 -#define SYSTEM_THREAD_STACK_SIZE 4096 +#define IDLE_THREAD_STACK_SIZE 40960 +#define SYSTEM_THREAD_STACK_SIZE 40960 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 4096 @@ -43,6 +43,8 @@ #define RT_PAGE_MAX_ORDER 11 #define RT_USING_MEMPOOL #define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE #define RT_USING_SMALL_MEM_AS_HEAP #define RT_USING_HEAP @@ -52,10 +54,11 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart1" -#define RT_VER_NUM 0x50000 +#define RT_VER_NUM 0x50001 #define ARCH_CPU_64BIT #define RT_USING_CACHE #define RT_USING_HW_ATOMIC +#define ARCH_ARM_BOOTWITH_FLUSH_CACHE #define ARCH_MM_MMU #define ARCH_ARM #define ARCH_ARM_MMU @@ -65,7 +68,7 @@ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 4096 +#define RT_MAIN_THREAD_STACK_SIZE 8192 #define RT_MAIN_THREAD_PRIORITY 10 #define RT_USING_MSH #define RT_USING_FINSH @@ -80,12 +83,18 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + #define RT_USING_DFS #define DFS_USING_POSIX #define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 #define DFS_FILESYSTEMS_MAX 4 #define DFS_FILESYSTEM_TYPES_MAX 4 -#define DFS_FD_MAX 16 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_RAMFS /* Device Drivers */ @@ -98,7 +107,10 @@ #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_PIN +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC /* Using USB */ @@ -109,6 +121,13 @@ /* POSIX (Portable Operating System Interface) layer */ +#define RT_USING_POSIX_FS +#define RT_USING_POSIX_DEVIO +#define RT_USING_POSIX_STDIO +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER /* Interprocess Communication (IPC) */ @@ -121,6 +140,8 @@ /* Utilities */ +#define RT_USING_RYM +#define YMODEM_USING_FILE_TRANSFER #define RT_USING_ADT /* RT-Thread Utestcases */ @@ -201,6 +222,9 @@ /* samples: kernel and components samples */ +#define PKG_USING_KERNEL_SAMPLES +#define PKG_USING_KERNEL_SAMPLES_LATEST_VERSION +#define PKG_USING_KERNEL_SAMPLES_EN /* entertainment: terminal games and other interesting software packages */ @@ -251,6 +275,7 @@ #define BSP_USING_GIC #define BSP_USING_GICV3 #define PHYTIUM_ARCH_AARCH64 +#define ARM_SPI_BIND_CPU_ID 0 /* Standalone Setting */ @@ -258,12 +283,19 @@ /* Board Configuration */ -#define TARGET_E2000Q +#define TARGET_E2000D #define TARGET_E2000 #define DEFAULT_DEBUG_PRINT_UART1 /* Components Configuration */ +#define USE_SPI +#define USE_FSPIM +#define USE_QSPI + +/* Qspi Configuration */ + +#define USE_FQSPI #define USE_SERIAL /* Usart Configuration */ diff --git a/bsp/phytium/aarch64/rtconfig.py b/bsp/phytium/aarch64/rtconfig.py index 9bb9671efb..26c597293d 100644 --- a/bsp/phytium/aarch64/rtconfig.py +++ b/bsp/phytium/aarch64/rtconfig.py @@ -3,26 +3,14 @@ import os # toolchains options ARCH ='aarch64' CPU ='cortex-a' -CROSS_TOOL ='gcc' - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = r'../../..' - +CROSS_TOOL = 'gcc' PLATFORM = 'gcc' -EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' -if os.getenv('AARCH64_CROSS_PATH'): - EXEC_PATH = os.getenv('AARCH64_CROSS_PATH') - print('EXEC_PATH = {}'.format(EXEC_PATH)) -else: - print('AARCH64_CROSS_PATH not found') - -BUILD = 'debug' +EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' +BUILD = 'debug' if PLATFORM == 'gcc': # toolchains - PREFIX = 'aarch64-none-elf-' + PREFIX = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' @@ -32,21 +20,26 @@ if PLATFORM == 'gcc': SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' + STRIP = PREFIX + 'strip' + CFPFLAGS = ' ' + AFPFLAGS = ' ' + DEVICE = ' -march=armv8-a -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' - DEVICE = ' -march=armv8-a -mtune=cortex-a72' - CFLAGS = DEVICE + ' -Wall' - AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__' - LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread_a64.map,-cref,-u,system_vectors -T link.lds -fdiagnostics-color=always' + CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always' + CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always' + AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_a64.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static' CPATH = '' LPATH = '' if BUILD == 'debug': - CFLAGS += ' -O0 -gdwarf-2' - AFLAGS += ' -gdwarf-2' + CFLAGS += ' -O0 -gdwarf-2' + CXXFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' else: - CFLAGS += ' -O2' + CFLAGS += ' -Os' + CXXFLAGS += ' -Os' + CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti' - CXXFLAGS = CFLAGS - -DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread_a64.dis\n' -POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_a64.bin\n' + SIZE + ' $TARGET \n' +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread_a64.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_a64.bin\n' + SIZE + ' $TARGET \n' \ No newline at end of file diff --git a/bsp/phytium/aarch64/sdkconfig.h b/bsp/phytium/aarch64/sdkconfig.h deleted file mode 100644 index d799f85053..0000000000 --- a/bsp/phytium/aarch64/sdkconfig.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: sdkconfig.h - * Date: 2022-10-09 15:04:36 - * LastEditTime: 2022-10-09 15:04:37 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#ifndef SDK_CONFIG_H__ -#define SDK_CONFIG_H__ - -#include "rtconfig.h" - -/* board */ - -/* E2000 */ - -#if defined(TARGET_E2000) - #define CONFIG_TARGET_E2000 -#endif - -#if defined(TARGET_E2000Q) - #define CONFIG_TARGET_E2000Q -#endif - -#if defined(TARGET_ARMV8_AARCH64) - #define CONFIG_TARGET_ARMV8_AARCH64 -#endif - -/* debug */ - -#ifdef LOG_VERBOS - #define CONFIG_LOG_VERBOS -#endif - -#ifdef LOG_ERROR - #define CONFIG_LOG_ERROR -#endif - -#ifdef LOG_WARN - #define CONFIG_LOG_WARN -#endif - -#ifdef LOG_INFO - #define CONFIG_LOG_INFO -#endif - -#ifdef LOG_DEBUG - #define CONFIG_LOG_DEBUG -#endif - -#ifdef BOOTUP_DEBUG_PRINTS - #define CONFIG_BOOTUP_DEBUG_PRINTS -#endif - -#endif diff --git a/bsp/phytium/board/SConscript b/bsp/phytium/board/SConscript index 0cf8e84721..2742d80f1a 100644 --- a/bsp/phytium/board/SConscript +++ b/bsp/phytium/board/SConscript @@ -2,21 +2,24 @@ from building import * cwd = GetCurrentDir() src = Glob('*.S') -src += Glob('*.c') +src += Glob('*.c') if GetDepend(['TARGET_E2000']): + src += Glob(cwd + '/e2000/memory_map.c') if GetDepend(['TARGET_E2000Q']): - src += Glob(cwd + '/e2000/q/parameters.c') + src += Glob(cwd + '/e2000/q/parameters.c') elif GetDepend(['TARGET_E2000D']): - src += Glob(cwd + '/e2000/d/parameters.c') + src += Glob(cwd + '/e2000/d/parameters.c') elif GetDepend(['TARGET_E2000S']): - src += Glob(cwd + '/e2000/s/parameters.c') + src += Glob(cwd + '/e2000/s/parameters.c') if GetDepend(['TARGET_F2000_4']): - src += Glob(cwd + '/d2000/parameters.c') + src += Glob(cwd + '/ft2004/memory_map.c') + src += Glob(cwd + '/d2000/parameters.c') if GetDepend(['TARGET_D2000']): - src += Glob(cwd + '/ft2004/parameters.c') + src += Glob(cwd + '/d2000/memory_map.c') + src += Glob(cwd + '/ft2004/parameters.c') CPPPATH = [cwd] diff --git a/bsp/phytium/board/board.c b/bsp/phytium/board/board.c index b02fd10b13..fe9aba293b 100644 --- a/bsp/phytium/board/board.c +++ b/bsp/phytium/board/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,6 +9,7 @@ * Date Author Notes * 2022-10-26 huanghe first commit * 2022-10-26 zhugengyu support aarch64 + * 2023-04-13 zhugengyu support RT-Smart * */ @@ -17,6 +18,13 @@ #include #include +#include /* TODO: why need application space when RT_SMART off */ +#include + +#ifdef RT_USING_SMART +#include +#include +#endif #include #if defined(TARGET_ARMV8_AARCH64) @@ -33,7 +41,6 @@ #include "fprintk.h" #include "fearly_uart.h" #include "fcpu_info.h" -#include "fpsci.h" #define LOG_DEBUG_TAG "BOARD" #define BSP_LOG_ERROR(format, ...) FT_DEBUG_PRINT_E(LOG_DEBUG_TAG, format, ##__VA_ARGS__) @@ -42,142 +49,36 @@ #define BSP_LOG_DEBUG(format, ...) FT_DEBUG_PRINT_D(LOG_DEBUG_TAG, format, ##__VA_ARGS__) /* mmu config */ -struct mem_desc platform_mem_desc[] = -#if defined(TARGET_E2000) -{ - { - 0x00U, - 0x00U + 0x40000000U, - 0x00U, - DEVICE_MEM - }, - { - 0x40000000U, - 0x40000000U + 0x10000000U, - 0x40000000U, - DEVICE_MEM - }, - { - 0x50000000U, - 0x50000000U + 0x30000000U, - 0x50000000U, - DEVICE_MEM - }, - { - 0x80000000U, - 0xffffffffU, - 0x80000000U, - NORMAL_MEM - }, -#if defined(TARGET_ARMV8_AARCH64) - { - 0x1000000000, - 0x1000000000 + 0x1000000000, - 0x1000000000, - DEVICE_MEM - }, - { - 0x2000000000, - 0x2000000000 + 0x2000000000, - 0x2000000000, - NORMAL_MEM - }, -#endif -}; -#elif defined(TARGET_F2000_4) || defined(TARGET_D2000) -{ - { - 0x80000000, - 0xFFFFFFFF, - 0x80000000, - DDR_MEM - }, - { - 0, //< QSPI - 0x1FFFFFFF, - 0, - DEVICE_MEM - }, - { - 0x20000000, // +#include + + +/* mmu config */ +#ifdef RT_USING_SMART +#if defined(TARGET_ARMV8_AARCH64) +struct mem_desc platform_mem_desc[] = +{ + { KERNEL_VADDR_START, + KERNEL_VADDR_START + 0x0fffffff, + (rt_size_t)ARCH_MAP_FAILED, + NORMAL_MEM + } +}; +#else +struct mem_desc platform_mem_desc[] = +{ + { KERNEL_VADDR_START, + KERNEL_VADDR_START + 0x10000000, + (rt_size_t)ARCH_MAP_FAILED, + NORMAL_MEM + } +}; +#endif + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]); +#else + +/* mmu config */ +struct mem_desc platform_mem_desc[] = +{ + { + 0x80000000, + 0xFFFFFFFF, + 0x80000000, + DDR_MEM + }, + { + 0, //< QSPI + 0x1FFFFFFF, + 0, + DEVICE_MEM + }, + { + 0x20000000, // +#include + +/* mmu config */ +#ifdef RT_USING_SMART +#if defined(TARGET_ARMV8_AARCH64) +struct mem_desc platform_mem_desc[] = +{ + { KERNEL_VADDR_START, + KERNEL_VADDR_START + 0x0fffffff, + (rt_size_t)ARCH_MAP_FAILED, + NORMAL_MEM + } +}; +#else +struct mem_desc platform_mem_desc[] = +{ + { KERNEL_VADDR_START, + KERNEL_VADDR_START + 0x10000000, + (rt_size_t)ARCH_MAP_FAILED, + NORMAL_MEM + } +}; +#endif +#else + +#if defined(TARGET_ARMV8_AARCH64) + +struct mem_desc platform_mem_desc[] = { + {KERNEL_VADDR_START, DDR_END_ADDRESS , KERNEL_VADDR_START, NORMAL_MEM}, + { + 0x28000000U, + 0x32B36FFFU, + 0x28000000U, + DEVICE_MEM + }, +}; +#else +struct mem_desc platform_mem_desc[] = +{ + { + 0x00U, + 0x00U + 0x40000000U, + 0x00U, + DEVICE_MEM + }, + { + 0x40000000U, + 0x40000000U + 0x10000000U, + 0x40000000U, + DEVICE_MEM + }, + { + 0x50000000U, + 0x50000000U + 0x30000000U, + 0x50000000U, + DEVICE_MEM + }, + { + 0x80000000U, + 0xffffffffU, + 0x80000000U, + NORMAL_MEM + }, +#if defined(TARGET_ARMV8_AARCH64) + { + 0x1000000000, + 0x1000000000 + 0x1000000000, + 0x1000000000, + DEVICE_MEM + }, + { + 0x2000000000, + 0x2000000000 + 0x2000000000, + 0x2000000000, + NORMAL_MEM + }, +#endif +}; + +#endif + +#endif + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]); diff --git a/bsp/phytium/board/e2000/q/parameters.c b/bsp/phytium/board/e2000/q/parameters.c index d3d3432c15..ed3fb0453e 100644 --- a/bsp/phytium/board/e2000/q/parameters.c +++ b/bsp/phytium/board/e2000/q/parameters.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -72,4 +72,4 @@ u32 GetCpuMaskToAffval(u32 *cpu_mask, u32 *cluster_id, u32 *target_list) } return 1; -} \ No newline at end of file +} diff --git a/bsp/phytium/board/ft2004/memory_map.c b/bsp/phytium/board/ft2004/memory_map.c new file mode 100644 index 0000000000..6dd42b0115 --- /dev/null +++ b/bsp/phytium/board/ft2004/memory_map.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-04-27 huanghe first version + * + */ + +#include "rtconfig.h" +#include +#include + +/* mmu config */ +struct mem_desc platform_mem_desc[] = +{ + { + 0x80000000, + 0xFFFFFFFF, + 0x80000000, + DDR_MEM + }, + { + 0, //< QSPI + 0x1FFFFFFF, + 0, + DEVICE_MEM + }, + { + 0x20000000, //config.instance_id].device, RT_CAN_EVENT_RX_IND); + FCAN_TEST_DEBUG("CAN%d irq recv frame callback.", instance_p->config.instance_id); +} + +static void CanErrorCallback(void *args) +{ + FCanCtrl *instance_p = (FCanCtrl *)args; + uintptr base_addr = instance_p->config.base_address; + FCAN_TEST_DEBUG("CAN %d is under error.", instance_p->config.instance_id); + FCAN_TEST_DEBUG("error_status is %x.", FCAN_READ_REG32(base_addr, FCAN_INTR_OFFSET)); + FCAN_TEST_DEBUG("rxerr_cnt is %x.", FCAN_ERR_CNT_RFN_GET(FCAN_READ_REG32(base_addr, FCAN_ERR_CNT_OFFSET))); + FCAN_TEST_DEBUG("txerr_cnt is %x.", FCAN_ERR_CNT_TFN_GET(FCAN_READ_REG32(base_addr, FCAN_ERR_CNT_OFFSET))); +} + +static void CanTxIrqCallback(void *args) +{ + FCanCtrl *instance_p = (FCanCtrl *)args; + rt_hw_can_isr(&drv_can[instance_p->config.instance_id].device, RT_CAN_EVENT_TX_DONE); + FCAN_TEST_DEBUG("CAN%d irq send frame callback.", instance_p->config.instance_id); +} + +static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg) +{ + RT_ASSERT(can); + RT_ASSERT(cfg); + struct phytium_can *drv_can; + drv_can = (struct phytium_can *)can->parent.user_data; + RT_ASSERT(drv_can); + FError status = FT_SUCCESS; + rt_kprintf("CAN%d begin to config.\n", drv_can->can_handle.config.instance_id); + +#if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) + if(drv_can->can_handle.config.instance_id == FCAN_INSTANCE_0) + { + FPinSetFunc(FIOCTRL_TJTAG_TDI_PAD, FPIN_FUNC1); /* can0-tx: func 1 */ + FPinSetFunc(FIOCTRL_SWDITMS_SWJ_PAD, FPIN_FUNC1); /* can0-rx: func 1 */ + } + else if(drv_can->can_handle.config.instance_id == FCAN_INSTANCE_1) + { + FPinSetFunc(FIOCTRL_NTRST_SWJ_PAD, FPIN_FUNC1); /* can1-tx: func 1 */ + FPinSetFunc(FIOCTRL_SWDO_SWJ_PAD, FPIN_FUNC1); /* can1-rx: func 1 */ + } + else + { + FCAN_TEST_ERROR("CAN id is under error."); + return RT_ERROR; + } +#elif defined(CONFIG_TARGET_E2000) + FIOPadSetCanMux(drv_can->can_handle.config.instance_id); +#endif + + /*CAN config init*/ + status = FCanCfgInitialize(&(drv_can->can_handle), FCanLookupConfig(drv_can->can_handle.config.instance_id)); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN %d initialize error, status = %#x.", drv_can->can_handle.config.instance_id, status); + return RT_ERROR; + } + + /*Set the baudrate*/ + FCanBaudrateConfig arb_segment_config; + FCanBaudrateConfig data_segment_config; + memset(&arb_segment_config, 0, sizeof(arb_segment_config)); + memset(&data_segment_config, 0, sizeof(data_segment_config)); +#if defined(RT_CAN_USING_CANFD) + arb_segment_config.auto_calc = TRUE; + arb_segment_config.baudrate = CAN1MBaud; /*CANFD arb baud defaults to 1M ,allowed to be modified*/ + arb_segment_config.segment = FCAN_ARB_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &arb_segment_config); + if (status != RT_EOK) + { + FCAN_TEST_DEBUG("CAN%d set arb segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + data_segment_config.auto_calc = TRUE; + data_segment_config.baudrate = cfg->baud_rate_fd; + data_segment_config.segment = FCAN_DATA_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &data_segment_config); + if (status != RT_EOK) + { + FCAN_TEST_DEBUG("CAN%d set data segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } +#else + arb_segment_config.auto_calc = TRUE; + arb_segment_config.baudrate = cfg->baud_rate; + arb_segment_config.segment = FCAN_ARB_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &arb_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set arb segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + data_segment_config.auto_calc = TRUE; + data_segment_config.baudrate = cfg->baud_rate; + data_segment_config.segment = FCAN_DATA_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &data_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set data segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } +#endif + + /*CAN filter function init*/ + for (int i = 0; i < FCAN_ACC_ID_REG_NUM; i++) + { + drv_can->filter.filter_index = i; + drv_can->filter.id = 0; + drv_can->filter.mask = FCAN_ACC_IDN_MASK; + status |= FCanIdMaskFilterSet(&(drv_can->can_handle), &(drv_can->filter)); + } + if (status != FT_SUCCESS) + { + FCAN_TEST_ERROR("CAN%d set mask filter failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + /* Identifier mask enable */ + FCanIdMaskFilterEnable(&(drv_can->can_handle)); + /* Transmit mode init , the default setting is normal mode */ + FCanSetMode(&(drv_can->can_handle), FCAN_PROBE_NORMAL_MODE); + /* enable can transfer */ + FCanEnable(&(drv_can->can_handle), RT_TRUE); + + return RT_EOK; +} + +static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) +{ + RT_ASSERT(can); + rt_uint32_t argval; + struct phytium_can *drv_can; + drv_can = (struct phytium_can *)can->parent.user_data; + RT_ASSERT(drv_can != RT_NULL); + rt_uint32_t cpu_id; + FCanIntrEventConfig intr_event; + FError status = FT_SUCCESS; + +#ifdef RT_CAN_USING_HDR + struct rt_can_filter_config *filter_cfg; +#endif + + switch (cmd) + { + case RT_DEVICE_CTRL_SET_INT: + GetCpuId(&cpu_id); + rt_hw_interrupt_set_target_cpus(drv_can->can_handle.config.irq_num, cpu_id); + argval = (rt_uint32_t) arg; + /*Open different interrupts*/ + if (argval == RT_DEVICE_CAN_INT_ERR) + { + intr_event.type = FCAN_INTR_EVENT_ERROR; + intr_event.handler = CanErrorCallback; + intr_event.param = (void *)(&(drv_can->can_handle)); + FCanRegisterInterruptHandler(&(drv_can->can_handle), &intr_event); + FCanInterruptEnable(&(drv_can->can_handle), intr_event.type); + } + if (argval == RT_DEVICE_FLAG_INT_TX) + { + intr_event.type = FCAN_INTR_EVENT_SEND; + intr_event.handler = CanTxIrqCallback; + intr_event.param = (void *)(&(drv_can->can_handle)); + FCanRegisterInterruptHandler(&(drv_can->can_handle), &intr_event); + FCanInterruptEnable(&(drv_can->can_handle), intr_event.type); + } + if (argval == RT_DEVICE_FLAG_INT_RX) + { + intr_event.type = FCAN_INTR_EVENT_RECV; + intr_event.handler = CanRxIrqCallback; + intr_event.param = (void *)(&(drv_can->can_handle)); + FCanRegisterInterruptHandler(&(drv_can->can_handle), &intr_event); + FCanInterruptEnable(&(drv_can->can_handle), intr_event.type); + } + rt_hw_interrupt_set_priority(drv_can->can_handle.config.irq_num, 16); + rt_hw_interrupt_install(drv_can->can_handle.config.irq_num, FCanIntrHandler, &(drv_can->can_handle), drv_can->name); + rt_hw_interrupt_umask(drv_can->can_handle.config.irq_num); + break; + + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + FCanEnable(&(drv_can->can_handle), RT_FALSE); + if (argval == RT_CAN_MODE_LISTEN) + { + FCanSetMode(&(drv_can->can_handle), FCAN_PROBE_MONITOR_MODE); + drv_can->device.config.mode = RT_CAN_MODE_LISTEN; + } + else if (argval == RT_CAN_MODE_NORMAL) + { + FCanSetMode(&(drv_can->can_handle), FCAN_PROBE_NORMAL_MODE); + drv_can->device.config.mode = RT_CAN_MODE_NORMAL; + } + FCanEnable(&(drv_can->can_handle), RT_TRUE); + break; + + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + if (argval != CAN1MBaud && + argval != CAN800kBaud && + argval != CAN500kBaud && + argval != CAN250kBaud && + argval != CAN125kBaud && + argval != CAN100kBaud && + argval != CAN50kBaud && + argval != CAN20kBaud && + argval != CAN10kBaud) + { + return RT_ERROR; + } + if (argval != drv_can->device.config.baud_rate) + { + FCanBaudrateConfig arb_segment_config; + FCanBaudrateConfig data_segment_config; + memset(&arb_segment_config, 0, sizeof(arb_segment_config)); + memset(&data_segment_config, 0, sizeof(data_segment_config)); + drv_can->device.config.baud_rate = argval; + FCanEnable(&(drv_can->can_handle), RT_FALSE); + arb_segment_config.auto_calc = TRUE; + arb_segment_config.baudrate = drv_can->device.config.baud_rate; + arb_segment_config.segment = FCAN_ARB_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &arb_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set arb segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + data_segment_config.auto_calc = TRUE; + data_segment_config.baudrate = drv_can->device.config.baud_rate; + data_segment_config.segment = FCAN_DATA_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &data_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set data segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + FCanEnable(&(drv_can->can_handle), RT_TRUE); + } + break; + + case RT_CAN_CMD_SET_BAUD_FD: + #if defined RT_CAN_USING_CANFD + argval = (rt_uint32_t) arg; + if (argval != drv_can->device.config.baud_rate_fd) + { + FCanBaudrateConfig arb_segment_config; + FCanBaudrateConfig data_segment_config; + memset(&arb_segment_config, 0, sizeof(arb_segment_config)); + memset(&data_segment_config, 0, sizeof(data_segment_config)); + drv_can->device.config.baud_rate = argval; + FCanEnable(&(drv_can->can_handle), RT_FALSE); + arb_segment_config.auto_calc = TRUE; + arb_segment_config.baudrate = CAN1MBaud; + arb_segment_config.segment = FCAN_ARB_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &arb_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set arb segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + data_segment_config.auto_calc = TRUE; + data_segment_config.baudrate = drv_can->device.config.baud_rate_fd; + data_segment_config.segment = FCAN_DATA_SEGMENT; + status = FCanBaudrateSet(&(drv_can->can_handle), &data_segment_config); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d set data segment baudrate failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + FCanEnable(&(drv_can->can_handle), RT_TRUE); + } + #endif + break; + + case RT_CAN_CMD_SET_FILTER: + #ifdef RT_CAN_USING_HDR + filter_cfg = (struct rt_can_filter_config *)arg; + FCanEnable(&(drv_can->can_handle), RT_FALSE); + for (int i = 0; i < filter_cfg->count; i++) + { + drv_can->filter.filter_index = i; + drv_can->filter.mask = filter_cfg->items[i].mask; + drv_can->filter.id = filter_cfg->items[i].id; + drv_can->filter.type = FCAN_STANDARD_FRAME; + status = FCanIdMaskFilterSet(&(drv_can->can_handle), &(drv_can->filter)); + if (status != FT_SUCCESS) + { + FCAN_TEST_ERROR("CAN%d set mask filter failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + } + FCanEnable(&(drv_can->can_handle), RT_TRUE); + #endif + break; + } + + return RT_EOK; +} + +static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num) +{ + RT_ASSERT(can); + RT_ASSERT(buf); + struct phytium_can *drv_can; + drv_can = (struct phytium_can *)can->parent.user_data; + RT_ASSERT(drv_can); + struct rt_can_msg *pmsg = (struct rt_can_msg *)buf; + FCanFrame can_frame = {0}; + + /* Check the parameters */ + RT_ASSERT(pmsg->len <= 8U); + + if (RT_CAN_STDID == pmsg->ide) + { + can_frame.canid = pmsg->id; + } + else + { + can_frame.canid = pmsg->id; + can_frame.canid |= CAN_EFF_FLAG; + } + if (RT_CAN_DTR == pmsg->rtr) + { + + } + else + { + can_frame.canid |= CAN_RTR_FLAG; + } + + can_frame.candlc = pmsg->len ; + + memcpy(can_frame.data, pmsg->data, 8); + return (FCanSend(&drv_can->can_handle, &can_frame) == RT_EOK) ? RT_EOK : -RT_ERROR; +} + +static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) +{ + RT_ASSERT(can); + RT_ASSERT(buf); + struct phytium_can *drv_can; + drv_can = (struct phytium_can *)can->parent.user_data; + RT_ASSERT(drv_can); + struct rt_can_msg *pmsg = (struct rt_can_msg *)buf; + FCanFrame recv_frame; + FError status = FT_SUCCESS; + + status = FCanRecv(&(drv_can->can_handle), &recv_frame); + if (status != FT_SUCCESS) + { + FCAN_TEST_DEBUG("CAN%d recv data failed.", drv_can->can_handle.config.instance_id); + return RT_ERROR; + } + if (CAN_EFF_FLAG & recv_frame.canid) + { + pmsg->ide = RT_CAN_EXTID; + pmsg->id = (recv_frame.canid & ~(RT_CAN_EXTID)); + } + else + { + pmsg->ide = RT_CAN_STDID; + pmsg->id = recv_frame.canid; + } + + if (CAN_RTR_FLAG & recv_frame.canid) + { + pmsg->id &= ~CAN_RTR_FLAG; + pmsg->rtr = RT_CAN_RTR; + } + else + { + pmsg->rtr = RT_CAN_DTR; + } + + /* get len */ + pmsg->len = recv_frame.candlc; + for (int i = 0; i < pmsg->len; i++) + { + pmsg->data[i] = recv_frame.data[i]; + } + /* get hdr */ + pmsg->hdr = 0; + + return RT_EOK; +} + +static const struct rt_can_ops _can_ops = +{ + _can_config, + _can_control, + _can_sendmsg, + _can_recvmsg, +}; + +int rt_hw_can_init(void) +{ + rt_err_t ret = RT_EOK; + for (int i = 0; i < (u32)FCAN_NUM; i++) + { + drv_can[i].device.config.ticks = 20000; + drv_can[i].device.config.baud_rate = 800000; + #ifdef RT_CAN_USING_CANFD + drv_can[i].device.config.baud_rate_fd = 800000; + #endif + drv_can[i].device.config.mode = RT_CAN_MODE_NORMAL; + drv_can[i].device.config.sndboxnumber = 1; + drv_can[i].device.config.msgboxsz = 1; + #ifdef RT_CAN_USING_HDR + drv_can[i].device.config.maxhdr = 1; + #endif + ret = rt_hw_can_register(&drv_can[i].device, + drv_can[i].name, + &_can_ops, + &drv_can[i]); + RT_ASSERT(ret == RT_EOK); + } + return (int)ret; +} +INIT_BOARD_EXPORT(rt_hw_can_init); + +/*can test example*/ +static rt_device_t can_dev; /* CAN device handle */ +static struct rt_semaphore rx_sem; +static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) +{ + /* The CAN generates an interrupt after receiving data, calls this callback function, and then sends the received semaphore */ + rt_sem_release(&rx_sem); + return RT_EOK; +} +static void can_rx_thread(void *parameter) +{ + int i; + rt_err_t res = RT_EOK; + struct rt_can_msg rxmsg = {0}; + rt_device_set_rx_indicate(can_dev, can_rx_call); + while (1) + { + /* The hdr value is - 1, which means reading data directly from the uselist */ + rxmsg.hdr = -1; + /* Blocking waiting to receive semaphore */ + res = rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + RT_ASSERT(res == RT_EOK); + /* Read a frame of data from CAN */ + rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg)); + /* Print data ID and conten */ + rt_kprintf("ID:%x\n", rxmsg.id); + rt_kprintf("DATA: "); + for (i = 0; i < 8; i++) + { + rt_kprintf("%2x ", rxmsg.data[i]); + } + + rt_kprintf("\n"); + } +} + +int can_sample(int argc, char *argv[]) +{ + struct rt_can_msg msg = {0}; + rt_err_t res = RT_EOK;; + rt_size_t size; + rt_thread_t thread; + char can_name[RT_NAME_MAX]; + + if (argc == 2) + { + rt_strncpy(can_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(can_name, "CAN0", RT_NAME_MAX); + } + /* Find CAN device */ + can_dev = rt_device_find(can_name); + if (!can_dev) + { + rt_kprintf("Find %s failed.\n", can_name); + return RT_ERROR; + } + + /* Initialize CAN receive signal quantity */ + res = rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + RT_ASSERT(res == RT_EOK); + + /* Open the CAN device in the way of interrupt reception and transmission */ + res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX); + rt_device_control(can_dev,RT_CAN_CMD_SET_BAUD, CAN1MBaud); + RT_ASSERT(res == RT_EOK); + + #ifdef RT_CAN_USING_HDR + struct rt_can_filter_item items[4] = + { + RT_CAN_FILTER_ITEM_INIT(0x3, 0, 0, 0, 0, RT_NULL, RT_NULL), + RT_CAN_FILTER_ITEM_INIT(0x3, 0, 0, 0, 0, RT_NULL, RT_NULL), + RT_CAN_FILTER_ITEM_INIT(0x3, 0, 0, 0, 0, RT_NULL, RT_NULL), + RT_CAN_FILTER_ITEM_INIT(0x3, 0, 0, 0, 0, RT_NULL, RT_NULL) + + }; + struct rt_can_filter_config cfg = {4, 1, items}; /* There are 4 filter tables in total */ + + /* Set the hardware filter table. After setting, only frames with id=0x03 can be received*/ + res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg); + RT_ASSERT(res == RT_EOK); + #endif + + /* Create data receiving thread */ + thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10); + if (thread != RT_NULL) + { + res = rt_thread_startup(thread); + RT_ASSERT(res == RT_EOK); + } + else + { + rt_kprintf("Create can_rx thread failed.\n"); + } + + msg.id = 0x78; /* ID = 0x78 */ + msg.ide = RT_CAN_STDID; /* Standard format */ + msg.rtr = RT_CAN_RTR; /* Data frame */ + msg.len = 8; /* Data length is 8 */ + /* Send CAN data */ + for (int i = 0; i < 10; i++) + { + /* 8-byte data to be sent */ + msg.data[0] = 0x00+i; + msg.data[1] = 0x11+i; + msg.data[2] = 0x22+i; + msg.data[3] = 0x33+i; + msg.data[4] = 0x44+i; + msg.data[5] = 0x55+i; + msg.data[6] = 0x66+i; + msg.data[7] = 0x77+i; + rt_device_write(can_dev, 0, &msg, sizeof(msg)); + } + + return res; +} +/* Enter can_sample command for testing */ +MSH_CMD_EXPORT(can_sample, can device sample); +#endif diff --git a/bsp/phytium/libraries/drivers/drv_can.h b/bsp/phytium/libraries/drivers/drv_can.h new file mode 100644 index 0000000000..cc21da0383 --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_can.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-03-20 zhangyan first version + * + */ + +#ifndef __DRV_CAN_H__ +#define __DRV_CAN_H__ + +#include + +#ifdef RT_USING_CAN + +#include "fcan.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int rt_hw_can_init(void); + +#ifdef __cplusplus +} +#endif + +#endif +#endif /* __DRV_CAN_H__ */ diff --git a/bsp/phytium/libraries/drivers/drv_qspi.c b/bsp/phytium/libraries/drivers/drv_qspi.c new file mode 100644 index 0000000000..bdd76a2eb1 --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_qspi.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-03-20 zhangyan first version + * + */ + +#include "drv_qspi.h" +#include "sdkconfig.h" + +#ifdef RT_USING_QSPI +#include +#include "rtdevice.h" +#include "fqspi_flash.h" +#include "fdebug.h" +#include "fpinctrl.h" + +#define FQSPI_DEBUG_TAG "FQSPI" +#define FQSPI_ERROR(format, ...) FT_DEBUG_PRINT_E(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_WARN(format, ...) FT_DEBUG_PRINT_W(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_INFO(format, ...) FT_DEBUG_PRINT_I(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_DEBUG(format, ...) FT_DEBUG_PRINT_D(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) + +#define DAT_LENGTH 128 +struct phytium_qspi_bus +{ + char *name; + rt_uint32_t init; /* 0 is init already */ + FQspiCtrl fqspi; + struct rt_spi_bus qspi_bus; +}; + +static struct phytium_qspi_bus phytium_qspi; /* phytium qspi bus handle */ +static struct rt_qspi_device *qspi_device; /* phytium device bus handle */ +static char qspi_bus_name[RT_NAME_MAX] = "QSPIBUS"; +static char qspi_dev_name[RT_NAME_MAX] = "QSPIDEV"; + +rt_err_t FQspiInit(FQspiCtrl *fqspi) +{ + u32 qspi_id = FQSPI0_ID; + FError ret = FT_SUCCESS; + +#if defined(CONFIG_TARGET_E2000) + FIOPadSetQspiMux(qspi_id, FQSPI_CS_0); + FIOPadSetQspiMux(qspi_id, FQSPI_CS_1); +#endif + + FQspiDeInitialize(fqspi); + FQspiConfig pconfig = *FQspiLookupConfig(qspi_id); + + /* Norflash init, include reset and read flash_size */ + ret = FQspiCfgInitialize(fqspi, &pconfig); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Qspi init failed.\n"); + return RT_ERROR; + } + else + { + FQSPI_DEBUG("Qspi init successfully.\n"); + } + + /* Detect connected flash infomation */ + ret = FQspiFlashDetect(fqspi); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Qspi flash detect failed.\n"); + return RT_ERROR; + } + else + { + FQSPI_DEBUG("Qspi flash detect successfully.\n"); + } + + return RT_EOK; +} + +static rt_err_t phytium_qspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration) +{ + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + struct phytium_qspi_bus *qspi_bus; + qspi_bus = (struct phytium_qspi_bus *) device->bus->parent.user_data; + rt_err_t ret = RT_EOK; + + ret = FQspiInit(&(qspi_bus->fqspi)); + if (RT_EOK != ret) + { + qspi_bus->init = RT_FALSE; + FQSPI_DEBUG("Qspi init failed!!!\n"); + return RT_ERROR; + } + qspi_bus->init = RT_EOK; + + return RT_EOK; +} + +static rt_uint32_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + RT_ASSERT(device != RT_NULL); + RT_ASSERT(message != RT_NULL); + struct phytium_qspi_bus *qspi_bus; + struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message; + rt_uint32_t cmd = qspi_message->instruction.content; + rt_uint32_t flash_addr = qspi_message->address.content; + rt_uint8_t *rcvb = message->recv_buf; + rt_uint8_t *sndb = message->send_buf; + FError ret = FT_SUCCESS; + + qspi_bus = (struct phytium_qspi_bus *) device->bus->parent.user_data; + + /*Distinguish the write mode according to different commands*/ + if (cmd == FQSPI_FLASH_CMD_PP||cmd == FQSPI_FLASH_CMD_QPP||cmd ==FQSPI_FLASH_CMD_4PP||cmd ==FQSPI_FLASH_CMD_4QPP ) + { + char *strs = (char *)message->send_buf; + rt_uint8_t len = strlen(strs) + 1; + rt_uint8_t *wr_buf = NULL; + wr_buf = (rt_uint8_t *)rt_malloc(DAT_LENGTH * sizeof(rt_uint8_t)); + + rt_memcpy(wr_buf, strs, len); + message->length = len; + ret = FQspiFlashErase(&(qspi_bus->fqspi), FQSPI_FLASH_CMD_SE, flash_addr); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to erase mem, test result 0x%x.\r\n", ret); + return RT_ERROR; + } + /* write norflash data */ + ret = FQspiFlashWriteData(&(qspi_bus->fqspi), cmd, flash_addr, wr_buf, len); + + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to write mem, test result 0x%x.\r\n", ret); + return RT_ERROR; + } + else + { + rt_kprintf("Write successfully!!!\r\n"); + } + rt_free(wr_buf); + + return RT_EOK; + } + + /*Distinguish the read mode according to different commands*/ + if (cmd == FQSPI_FLASH_CMD_READ||cmd == FQSPI_FLASH_CMD_4READ||cmd == FQSPI_FLASH_CMD_FAST_READ||cmd == FQSPI_FLASH_CMD_4FAST_READ|| + cmd == FQSPI_FLASH_CMD_DUAL_READ||cmd == FQSPI_FLASH_CMD_QIOR||cmd == FQSPI_FLASH_CMD_4QIOR) + { + rt_uint8_t *rd_buf = NULL; + rd_buf = (rt_uint8_t *)rt_malloc(DAT_LENGTH * sizeof(rt_uint8_t)); + + ret |= FQspiFlashReadDataConfig(&(qspi_bus->fqspi), cmd); + + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to config read, test result 0x%x.\r\n", ret); + return RT_ERROR; + } + /* read norflash data */ + size_t read_len = FQspiFlashReadData(&(qspi_bus->fqspi), flash_addr, rd_buf, DAT_LENGTH); + message->length = read_len; + if (read_len != DAT_LENGTH) + { + FQSPI_DEBUG("Failed to read mem, read len = %d.\r\n", read_len); + return RT_ERROR; + } + else + { + rt_kprintf("Read successfully!!!\r\n"); + message->recv_buf = rd_buf; + rt_free(rd_buf); + } + FtDumpHexByte(message->recv_buf, DAT_LENGTH); + + return RT_EOK; + } + + if (rcvb) + { + if (cmd == FQSPI_FLASH_CMD_RDID||cmd == FQSPI_FLASH_CMD_RDSR1||cmd == FQSPI_FLASH_CMD_RDSR2 ||cmd == FQSPI_FLASH_CMD_RDSR3) + { + ret |= FQspiFlashSpecialInstruction(&(qspi_bus->fqspi), cmd, rcvb, sizeof(rcvb)); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to read flash information.\n"); + return RT_ERROR; + } + } + + return RT_EOK; + } + + if (sndb) + { + ret |= FQspiFlashEnableWrite(&(qspi_bus->fqspi)); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to enable flash reg write.\n"); + return RT_ERROR; + } + + ret |= FQspiFlashWriteReg(&(qspi_bus->fqspi), cmd, sndb, 1); + if (FT_SUCCESS != ret) + { + FQSPI_DEBUG("Failed to write flash reg.\n"); + return RT_ERROR; + } + + return RT_EOK; + } +} + +static struct rt_spi_ops phytium_qspi_ops = +{ + .configure = phytium_qspi_configure, + .xfer = phytium_qspi_xfer, +}; + +rt_err_t phytium_qspi_bus_attach_device(const char *bus_name, const char *device_name) +{ + struct rt_qspi_device *qspi_device; + rt_err_t result = RT_EOK; + RT_ASSERT(bus_name != RT_NULL); + RT_ASSERT(device_name != RT_NULL); + + qspi_device = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device)); + if (qspi_device == RT_NULL) + { + FQSPI_DEBUG("Qspi bus attach device failed."); + result = RT_ENOMEM; + goto __exit; + } + + result = rt_spi_bus_attach_device(&(qspi_device->parent), device_name, bus_name, RT_NULL); +__exit: + if (result != RT_EOK) + { + if (qspi_device) + { + rt_free(qspi_device); + + } + + return result; +} +} + +int rt_hw_qspi_init(void) +{ + int i = 0; + int result = RT_EOK; + phytium_qspi.qspi_bus.parent.user_data = &phytium_qspi; + + if(rt_qspi_bus_register(&phytium_qspi.qspi_bus, qspi_bus_name , &phytium_qspi_ops) == RT_EOK) + { + rt_kprintf("Qspi bus register successfully!!!\n"); + } + else + { + FQSPI_DEBUG("Qspi bus register Failed!!!\n"); + result = -RT_ERROR; + } + + return result; +} +INIT_BOARD_EXPORT(rt_hw_qspi_init); + +/*example*/ +struct rt_spi_message write_message; +struct rt_spi_message read_message; + +rt_err_t qspi_init() +{ + rt_err_t res = RT_EOK; + res = phytium_qspi_bus_attach_device(qspi_bus_name, qspi_dev_name); + RT_ASSERT(res == RT_EOK); + qspi_device = (struct rt_qspi_device *)rt_device_find(qspi_dev_name); + + return res; +} + +/*read cmd example message improvement*/ +void ReadCmd(struct rt_spi_message *spi_message) +{ + struct rt_qspi_message *message = (struct rt_qspi_message*) spi_message; + message->address.content = 0x360000 ;/*Flash address*/ + message->instruction.content = 0x03 ;/*read cmd*/ + rt_qspi_transfer_message(qspi_device, message); +} + +/*write cmd example message improvement*/ +void WriteCmd(struct rt_spi_message *spi_message) +{ + struct rt_qspi_message *message = (struct rt_qspi_message*) spi_message; + message->address.content = 0x360000 ;/*Flash address*/ + message->instruction.content = 0x02 ;/*write cmd*/ + rt_qspi_transfer_message(qspi_device, message); +} + +/*write cmd example message improvement*/ +void qspi_thread(void *parameter) +{ + rt_err_t res; + + qspi_init(); + /*Read and write flash chip fixed area repeatedly*/ + write_message.send_buf = "111111111111111111111111"; + WriteCmd(&write_message); + ReadCmd(&read_message); + + write_message.send_buf = "222222222222222222222222"; + WriteCmd(&write_message); + ReadCmd(&read_message); + + write_message.send_buf = "333333333333333333333333"; + WriteCmd(&write_message); + ReadCmd(&read_message); + + rt_uint8_t recv; + rt_uint8_t cmd = 0x9F;/*read the flash status reg2*/ + res = rt_qspi_send_then_recv(qspi_device, &cmd, sizeof(cmd), &recv, sizeof(recv)); + RT_ASSERT(res!=RT_EOK); + + rt_kprintf("The status reg = %x \n" ,recv); + + return 0; +} + +rt_err_t qspi_sample(int argc, char *argv[]) +{ + rt_thread_t thread; + rt_err_t res; + thread = rt_thread_create("qspi_thread", qspi_thread, RT_NULL, 1024, 25, 10); + res = rt_thread_startup(thread); + RT_ASSERT(res==RT_EOK); + + return res; + +} +/* Enter qspi_sample command for testing */ +MSH_CMD_EXPORT(qspi_sample, qspi sample); +#endif diff --git a/bsp/phytium/libraries/drivers/drv_qspi.h b/bsp/phytium/libraries/drivers/drv_qspi.h new file mode 100644 index 0000000000..32af7f34bb --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_qspi.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2023-03-20 zhangyan first version + * + */ + +#ifndef __DRT_QSPI_H__ +#define __DRT_QSPI_H__ + +#include +#ifdef RT_USING_QSPI +#define PHYTIUM_QSPI_NAME "qspi" + +#ifdef __cplusplus +extern "C" +{ +#endif + +rt_err_t phytium_qspi_bus_attach_device(const char *bus_name, const char *device_name); + +#ifdef __cplusplus +} +#endif +#endif +#endif // !DRT_QSPI_H + diff --git a/bsp/phytium/libraries/drivers/drv_spi.c b/bsp/phytium/libraries/drivers/drv_spi.c new file mode 100644 index 0000000000..f7d537256d --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_spi.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2022-11-10 liqiaozhong first commit + * 2023-03-08 liqiaozhong support 4 spis and qspi working together + * + */ +#include +#include +#include "interrupt.h" + +#include +#include "fdebug.h" + +#if defined(TARGET_E2000) +#include "fparameters.h" +#endif + +#include "fcpu_info.h" +#include "fkernel.h" +#include "ftypes.h" +#include "fsleep.h" + +#ifdef RT_USING_SPI + +#include + +#include "fspim.h" +#include "fspim_hw.h" /* include low-level header file for internal probe */ +#include "drv_spi.h" +/************************** Constant Definitions *****************************/ +/**************************** Type Definitions *******************************/ +/************************** Variable Definitions *****************************/ +#ifdef RT_USING_SPIM0 + static struct drv_spi _RTSpim0; +#endif + +#ifdef RT_USING_SPIM1 + static struct drv_spi _RTSpim1; +#endif + +#ifdef RT_USING_SPIM2 + static struct drv_spi _RTSpim2; +#endif + +#ifdef RT_USING_SPIM3 + static struct drv_spi _RTSpim3; +#endif + +static struct rt_spi_device *spi_device = RT_NULL; +static struct rt_event rx_done_event; +/***************** Macros (Inline Functions) Definitions *********************/ +#define FSPIM_DEBUG_TAG "SPIM" +#define FSPIM_ERROR(format, ...) FT_DEBUG_PRINT_E(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_WARN(format, ...) FT_DEBUG_PRINT_W(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_INFO(format, ...) FT_DEBUG_PRINT_I(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) + +#define EVENT_RX_DONE (1 << 1) +/*******************************Api Functions*********************************/ +static rt_err_t spim_configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration); +static rt_uint32_t spim_xfer(struct rt_spi_device* device, struct rt_spi_message* message); + +static FError FSpimSetupInterrupt(FSpim *instance_p) +{ + FASSERT(instance_p); + FSpimConfig *config_p = &instance_p->config; + uintptr base_addr = config_p->base_addr; + u32 cpu_id = 0; + + GetCpuId(&cpu_id); + FSPIM_DEBUG("cpu_id is %d, irq_num is %d\n", cpu_id, config_p->irq_num); + config_p->irq_prority = 0xd0; + rt_hw_interrupt_set_target_cpus(config_p->irq_num, cpu_id); + rt_hw_interrupt_set_priority(config_p->irq_num, config_p->irq_prority); + + /* register intr callback */ + rt_hw_interrupt_install(config_p->irq_num, + FSpimInterruptHandler, + instance_p, + NULL); + + /* enable tx fifo overflow / rx overflow / rx full */ + FSpimMaskIrq(base_addr, FSPIM_IMR_ALL_BITS); + + /* enable irq */ + rt_hw_interrupt_umask(config_p->irq_num); + + return FSPIM_SUCCESS; +} + +static void rt_ft_send_event_done(void *instance_p, void *param) +{ + FASSERT(instance_p); + rt_event_send(&rx_done_event, EVENT_RX_DONE); + return; +} + +static const struct rt_spi_ops spim_ops = +{ + .configure = spim_configure, + .xfer = spim_xfer +}; + +static rt_err_t spim_configure(struct rt_spi_device *device, + struct rt_spi_configuration *configuration) +{ + FError ret = FSPIM_SUCCESS; + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + struct drv_spi *user_data_cfg = device->parent.user_data; + FSpimConfig input_cfg = *FSpimLookupConfig(user_data_cfg->spi_id); + FSpimConfig *set_input_cfg = &input_cfg; + + /* set fspim device according to configuration */ + if (configuration->mode & RT_SPI_CPOL) + { + set_input_cfg->cpol = FSPIM_CPOL_HIGH; + } + else + { + set_input_cfg->cpol = FSPIM_CPOL_LOW; + } + if (configuration->mode & RT_SPI_CPHA) + { + set_input_cfg->cpha = FSPIM_CPHA_2_EDGE; + } + else + { + set_input_cfg->cpha = FSPIM_CPHA_1_EDGE; + } + + if (configuration->data_width == 8) + { + set_input_cfg->n_bytes = FSPIM_1_BYTE; + } + else if (configuration->data_width == 16) + { + set_input_cfg->n_bytes = FSPIM_2_BYTE; + } + + /* send spi_cfg to RT-Thread sys */ + ret = FSpimCfgInitialize(&user_data_cfg->spim_instance, &input_cfg); + if (FSPIM_SUCCESS != ret) + return RT_ERROR; + + /* irq setting */ + ret = FSpimSetupInterrupt(&user_data_cfg->spim_instance); + if (FSPIM_SUCCESS != ret) + return RT_ERROR; + FSpimRegisterIntrruptHandler(&user_data_cfg->spim_instance, FSPIM_INTR_EVT_RX_DONE, rt_ft_send_event_done, NULL); + + return ret; +} + +static rt_uint32_t spim_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->parent.user_data != RT_NULL); + RT_ASSERT(message != RT_NULL); + rt_size_t message_length; + rt_uint8_t *recv_buf; + const rt_uint8_t *send_buf; + + /* recv spi_cfg from RT-Thread sys */ + struct drv_spi *user_data_xfer = device->parent.user_data; + FSpim *xfer_spim_instance = &user_data_xfer->spim_instance; + + FError tx_rx_result = FSPIM_SUCCESS; + message_length = message->length; + recv_buf = message->recv_buf; + send_buf = message->send_buf; + + if (message->cs_take) + { + FSpimSetChipSelection(xfer_spim_instance, TRUE); + } + + if (message_length > 0) + { + if (send_buf == RT_NULL && recv_buf != RT_NULL) + { + /* receive message */ + tx_rx_result = FSpimTransferByInterrupt(xfer_spim_instance, RT_NULL, recv_buf, message_length); + } + else if (send_buf != RT_NULL && recv_buf == RT_NULL) + { + /* send message */ + tx_rx_result = FSpimTransferByInterrupt(xfer_spim_instance, send_buf, RT_NULL, message_length); + } + else if (send_buf != RT_NULL && recv_buf != RT_NULL) + { + /* not supported yet */ + rt_kprintf("Do not support the situation that send_buf and recv_buf both not equal to 0."); + } + } + + if (FSPIM_SUCCESS != tx_rx_result) + { + rt_kprintf("FSpimTransferByInterrupt() fail!!!"); + message_length = 0; + } + + if (rt_event_recv(&rx_done_event, (EVENT_RX_DONE), + (RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), + RT_WAITING_FOREVER, RT_NULL) != RT_EOK) + { + rt_kprintf("Wait rx timeout!!!\n"); + message_length = 0; + } + + if (message->cs_release) + { + FSpimSetChipSelection(xfer_spim_instance, FALSE); + } + + return message_length; +} + +int ft_spi_init(void) +{ + rt_err_t result; + static struct rt_spi_bus spim_bus; + + /* event creat */ + if (RT_EOK != rt_event_init(&rx_done_event, "rx_done_event", RT_IPC_FLAG_FIFO)) + { + rt_kprintf("Create event failed.\n"); + return RT_ERROR; + } + + /* spi bus init */ + result = rt_spi_bus_register(&spim_bus, "spi0", &spim_ops); + RT_ASSERT((struct rt_spi_device *)rt_device_find("spi0")); + rt_kprintf("Spi bus spi0 init\n"); + + /* spi device init and attach to bus */ + #ifdef RT_USING_SPIM0 + _RTSpim0.spi_id = FSPI0_ID; + result = rt_spi_bus_attach_device(&_RTSpim0.device, "spi00", "spi0", &_RTSpim0); + spi_device = (struct rt_spi_device *)rt_device_find("spi00"); + if (RT_NULL == spi_device) + { + rt_kprintf("Spi init failed -> can't find spi00 device!\n"); + return RT_ERROR; + } + rt_kprintf("Spi master device spi00 init.\n"); + #endif + + #ifdef RT_USING_SPIM1 + _RTSpim1.spi_id = FSPI1_ID; + result = rt_spi_bus_attach_device(&_RTSpim1.device, "spi01", "spi0", &_RTSpim1); + spi_device = (struct rt_spi_device *)rt_device_find("spi01"); + if (RT_NULL == spi_device) + { + rt_kprintf("Spi init failed -> can't find spi01 device!\n"); + return RT_ERROR; + } + rt_kprintf("Spi master device spi01 init.\n"); + #endif + + #ifdef RT_USING_SPIM2 + _RTSpim2.spi_id = FSPI2_ID; + result = rt_spi_bus_attach_device(&_RTSpim2.device, "spi02", "spi0", &_RTSpim2); + spi_device = (struct rt_spi_device *)rt_device_find("spi02"); + if (RT_NULL == spi_device) + { + rt_kprintf("Spi init failed -> can't find spi02 device!\n"); + return RT_ERROR; + } + rt_kprintf("Spi master device spi02 init.\n"); + #endif + + #ifdef RT_USING_SPIM3 + _RTSpim3.spi_id = FSPI3_ID; + result = rt_spi_bus_attach_device(&_RTSpim3.device, "spi03", "spi0", &_RTSpim3); + spi_device = (struct rt_spi_device *)rt_device_find("spi03"); + if (RT_NULL == spi_device) + { + rt_kprintf("Spi init failed -> can't find spi03 device!\n"); + return RT_ERROR; + } + rt_kprintf("Spi master device spi03 init.\n"); + #endif + + + return result; +} +INIT_DEVICE_EXPORT(ft_spi_init); + +/* spi test example */ +static void fspim_test_sample(int argc, char *argv[]) +{ + rt_uint8_t send_to_flash_id = 0x9f; /* Flash cmd */ + rt_uint8_t recv_from_falsh_id1[5] = {0}; + rt_uint8_t recv_from_falsh_id2[5] = {0}; + + /* find the spi device to get the device handle */ + spi_device = (struct rt_spi_device *)rt_device_find("spi02"); + if (!spi_device) + { + rt_kprintf("fspim_test_sample run failed! can't find spi02 device!\n"); + } + else + { + static struct rt_spi_message msg1, msg2; + + msg1.send_buf = &send_to_flash_id; + msg1.recv_buf = RT_NULL; + msg1.length = 1; + msg1.cs_take = 1; + msg1.cs_release = 0; + msg1.next = &msg2; + + msg2.send_buf = RT_NULL; + msg2.recv_buf = recv_from_falsh_id2; + msg2.length = 5; + msg2.cs_take = 0; + msg2.cs_release = 1; + msg2.next = RT_NULL; + + /* send the command to read the ID using rt_spi_send_then_recv() */ + rt_spi_send_then_recv(spi_device, &send_to_flash_id, 1, recv_from_falsh_id1, 5); + rt_kprintf("use rt_spi_send_then_recv() read flash ID is:0x%x 0x%x 0x%x 0x%x 0x%x\n", recv_from_falsh_id1[0], recv_from_falsh_id1[1], recv_from_falsh_id1[2], recv_from_falsh_id1[3], recv_from_falsh_id1[4]); + + /* send the command to read the ID using rt_spi_transfer_message() */ + rt_spi_transfer_message(spi_device, &msg1); + rt_kprintf("use rt_spi_transfer_message() read flash ID is:0x%x 0x%x 0x%x 0x%x 0x%x\n", recv_from_falsh_id2[0], recv_from_falsh_id2[1], recv_from_falsh_id2[2], recv_from_falsh_id2[3], recv_from_falsh_id2[4]); + } +} +MSH_CMD_EXPORT(fspim_test_sample, "fspim test sample"); +#endif diff --git a/bsp/phytium/libraries/drivers/drv_spi.h b/bsp/phytium/libraries/drivers/drv_spi.h new file mode 100644 index 0000000000..be5a6aab7b --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_spi.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2022-11-10 liqiaozhong first commit + * 2023-03-08 liqiaozhong support 4 spis and qspi working together + */ +#ifndef __DRV_SPI_H__ +#define __DRV_SPI_H__ + +#include + +struct drv_spi +{ + u32 spi_id; + FSpim spim_instance; + struct rt_spi_device device; +}; + + +#endif + + diff --git a/bsp/phytium/libraries/drivers/drv_usart.c b/bsp/phytium/libraries/drivers/drv_usart.c index 788456040a..7601346b5f 100644 --- a/bsp/phytium/libraries/drivers/drv_usart.c +++ b/bsp/phytium/libraries/drivers/drv_usart.c @@ -8,10 +8,13 @@ * Change Logs: * Date Author Notes * 2022-10-26 huanghe first commit - * + * 2023-04-27 huanghe support RT-Smart */ #include "board.h" + +#include + #include "drv_usart.h" #include "interrupt.h" #include "fpl011.h" @@ -42,6 +45,10 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co uart_hw = uart->handle; config = *(const FPl011Config *)FPl011LookupConfig(uart->config.uart_instance); +#ifdef RT_USING_SMART + config.base_address = (uintptr)rt_ioremap((void*)config.base_address, 0x1000); +#endif + RT_ASSERT(FPl011CfgInitialize(uart_hw, &config) == FT_SUCCESS); FPl011SetHandler(uart_hw, Ft_Os_Uart_Callback, serial); @@ -129,13 +136,13 @@ static int uart_putc(struct rt_serial_device *serial, char c) return 1; } -u8 FPl011RecvByteNoBlocking(u32 addr) +u32 FPl011RecvByteNoBlocking(uintptr addr) { u32 recieved_byte; - while (FUART_ISRECEIVEDATA(addr)) + while (FUART_RECEIVEDATAEMPTY(addr)) { - return 0xff; + return 0xffff; } recieved_byte = FUART_READREG32(addr, FPL011DR_OFFSET); return recieved_byte; @@ -152,14 +159,13 @@ static int uart_getc(struct rt_serial_device *serial) uart_ptr = uart->handle; ch = FPl011RecvByteNoBlocking(uart_ptr->config.base_address); - if (ch == 0xff) + if (ch == 0xffff) { ch = -1; - rt_kprintf("") ; } else { - // + ch &= 0xff; } return ch; @@ -176,6 +182,7 @@ static const struct rt_uart_ops _uart_ops = #define RT_USING_UART0 #define RT_USING_UART1 +#define RT_USING_UART2 #ifdef RT_USING_UART0 @@ -188,6 +195,11 @@ static const struct rt_uart_ops _uart_ops = static struct drv_usart _RtUart1; #endif +#ifdef RT_USING_UART2 + static FPl011 Ft_Uart2; + static struct drv_usart _RtUart2; +#endif + int rt_hw_uart_init(void) { struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; @@ -196,7 +208,6 @@ int rt_hw_uart_init(void) config.bufsz = RT_SERIAL_RB_BUFSZ; _RtUart0.serial.ops = &_uart_ops; _RtUart0.serial.config = config; - // Ft_Uart0.config.instance_id = FUART0_ID; _RtUart0.handle = &Ft_Uart0; _RtUart0.config.uart_instance = FUART0_ID; @@ -213,7 +224,6 @@ int rt_hw_uart_init(void) config.bufsz = RT_SERIAL_RB_BUFSZ; _RtUart1.serial.ops = &_uart_ops; _RtUart1.serial.config = config; - // Ft_Uart1.config.instance_id = FUART1_ID; _RtUart1.handle = &Ft_Uart1; _RtUart1.config.uart_instance = FUART1_ID; @@ -226,6 +236,24 @@ int rt_hw_uart_init(void) &_RtUart1); #endif + +#ifdef RT_USING_UART2 + config.bufsz = RT_SERIAL_RB_BUFSZ; + _RtUart2.serial.ops = &_uart_ops; + _RtUart2.serial.config = config; + _RtUart2.handle = &Ft_Uart2; + + _RtUart2.config.uart_instance = FUART2_ID; + _RtUart2.config.isr_priority = 0xd0; + _RtUart2.config.isr_event_mask = (RTOS_UART_ISR_OEIM_MASK | RTOS_UART_ISR_BEIM_MASK | RTOS_UART_ISR_PEIM_MASK | RTOS_UART_ISR_FEIM_MASK | RTOS_UART_ISR_RTIM_MASK | RTOS_UART_ISR_RXIM_MASK); + _RtUart2.config.uart_baudrate = 115200; + + rt_hw_serial_register(&_RtUart2.serial, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &_RtUart2); +#endif + + return 0; } INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/phytium/libraries/drivers/drv_usart.h b/bsp/phytium/libraries/drivers/drv_usart.h index f82b3dc4d3..ed7e532c8c 100644 --- a/bsp/phytium/libraries/drivers/drv_usart.h +++ b/bsp/phytium/libraries/drivers/drv_usart.h @@ -8,7 +8,7 @@ * Change Logs: * Date Author Notes * 2022-10-26 huanghe first commit - * + * 2023-04-27 huanghe support RT-Smart */ #ifndef __DRV_USART_H__ diff --git a/bsp/phytium/libraries/drivers/drv_xmac.c b/bsp/phytium/libraries/drivers/drv_xmac.c new file mode 100644 index 0000000000..61f5dbfb40 --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_xmac.c @@ -0,0 +1,22 @@ +/* + * @Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * @FilePath: drv_xmac.c + * @Date: 2023-04-19 15:19:29 + * @LastEditTime: 2023-04-19 15:19:29 + * @Description: This file is for + * + * @Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + */ diff --git a/bsp/phytium/libraries/drivers/drv_xmac.h b/bsp/phytium/libraries/drivers/drv_xmac.h new file mode 100644 index 0000000000..c935747e24 --- /dev/null +++ b/bsp/phytium/libraries/drivers/drv_xmac.h @@ -0,0 +1,22 @@ +/* + * @Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * @FilePath: drv_xmac.h + * @Date: 2023-04-19 15:19:39 + * @LastEditTime: 2023-04-19 15:19:40 + * @Description: This file is for + * + * @Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + */ diff --git a/bsp/phytium/libraries/examples/spi_sfud_sample.c b/bsp/phytium/libraries/examples/spi_sfud_sample.c new file mode 100644 index 0000000000..ed9d0423ac --- /dev/null +++ b/bsp/phytium/libraries/examples/spi_sfud_sample.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Email: opensource_embedded@phytium.com.cn + * + * Change Logs: + * Date Author Notes + * 2022-11-20 liqiaozhong first commit + * 2022-03-08 liqiaozhong add format function and mount table + */ +#include +#include + +#if defined (RT_USING_SFUD) && defined(RT_USING_DFS) + +#include +#include +#include +#include +#include +#include +#include "spi_flash.h" +#include "spi_flash_sfud.h" + +#include "fdebug.h" +#include "fparameters_comm.h" + +#include "fspim.h" +/************************** Variable Definitions *****************************/ +sfud_flash_t spim_flash = RT_NULL; +const struct dfs_mount_tbl mount_table[] = +{ + { "flash2", "/", "elm", 0, RT_NULL }, + {0}, +}; +/***************** Macros (Inline Fungoctions) Definitions *********************/ +#define FSPIM_DEBUG_TAG "SPIM" +#define FSPIM_ERROR(format, ...) FT_DEBUG_PRINT_E(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_WARN(format, ...) FT_DEBUG_PRINT_W(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_INFO(format, ...) FT_DEBUG_PRINT_I(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSPIM_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) + +/*******************************Api Functions*********************************/ +static int spi_flash_sfud_init(void) +{ + if (RT_NULL == rt_sfud_flash_probe("flash2", "spi02")) + { + rt_kprintf("rt_sfud_flash_probe failed\n"); + return RT_ERROR; + } + spim_flash = rt_sfud_flash_find_by_dev_name("flash2"); + if (RT_NULL == spim_flash) + { + rt_kprintf("Flash init failed -> can't find flash2 device!\n"); + return RT_ERROR; + } + rt_kprintf("Spi flash device flash2 init\n"); + rt_kprintf("Flash device: flash2 info\nmf_id: 0x%x\ntype_id: 0x%x\ncapacity_id: 0x%x\nerase granularity: %lu\n", + spim_flash->chip.mf_id, + spim_flash->chip.type_id, + spim_flash->chip.capacity_id, + spim_flash->chip.erase_gran); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(spi_flash_sfud_init); + +/* format the flash with elm environment */ +static int flash_format_operation(void) +{ + int result = RT_EOK; + result = dfs_mkfs("elm", "flash2"); + return result; +} +INIT_ENV_EXPORT(flash_format_operation); + +#endif /* RT_USING_SFUD || RT_USING_DFS */ diff --git a/bsp/phytium/libraries/standalone/README.md b/bsp/phytium/libraries/standalone/README.md index a9dbcff01a..8011132ab3 100644 --- a/bsp/phytium/libraries/standalone/README.md +++ b/bsp/phytium/libraries/standalone/README.md @@ -1,17 +1,23 @@ # Phytium-Standalone-SDK -**v0.3.1** [ReleaseNote](./doc/ChangeLog.md) +**v1.0.0** [ReleaseNote](./doc/ChangeLog.md) ## 1. 项目概要 -### 1.1 基本介绍 +### 1.1 仓库介绍 + +本项目代码仓库整体共分为两个分支: +master 分支:开发分支,用于保存最新的协作开发代码以及bug修复后的代码。其只要求保障新功能基本正确并且能够满足基本的使用需求,并没有经过系统性和复杂条件下的测试。 +release 分支:发布分支,包含核心启动代码、芯片外设驱动、用户使用例程和构建的脚本工具。用于保存经过系统性测试的代码并对外发布版本,默认下载此分支的代码。 + +### 1.2 基本介绍 本项目发布了 Phytium 系列 CPU 的 嵌入式软件开发工具包,包括板级支持包、第三方开源中间件、交叉编译构建工具、及其 Baremetal 参考例程,在支持多平台裸机应用开发的基础上,能够为多种RTOS提供外设驱动和配置构建工具。 ![LetterShell](./doc/fig/letter_shell.png) -### 1.2 系统架构 +### 1.3 系统架构 本项目的整体设计如下所示,自下而上可以分为平台层、组件层、框架层和应用层。 @@ -26,7 +32,7 @@ - 应用层(Application)提供了应用开发模板和例程,帮助开发者迅速熟悉SDK的使用,进行不同类型的应用程序开发 -### 1.3. 源代码结构 +### 1.4 源代码结构 ``` . @@ -105,9 +111,8 @@ FT-2000/4 是一款面向桌面应用的高性能通用 4 核处理器。每 2 - 集成 34 Lane PCIE3.0 接口:2 个 X16(每个可拆分成 2 个 X8),2 个 X1 - 集成 2 个 GMAC,RGMII 接口,支持 10/100/1000 自适应 - 集成 1 个 SD 卡控制器,兼容 SD 2.0 规范 -- 集成 1 个 HDAudio,支持音频输出,可同时支持最多 4 个 Codec -- 集成 SM2、SM3、SM4 模块 -- 集成 4 个 UART,1 个 LPC,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通 用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) +- 集成 加密计算单元 +- 集成 4 个 UART,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通 用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) - 集成温度传感器 ### 3.2 D2000 @@ -123,39 +128,55 @@ D2000 是一款面向桌面应用的高性能通用 8 核处理器。每 2 个 - 集成 1 个 SD 卡控制器,兼容 SD 2.0 规范 - 集成 1 个 HDAudio,支持音频输出,可同时支持最多 4 个 Codec - 集成 SM2、SM3、SM4、SM9 模块 -- 集成 4 个 UART,1 个 LPC,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) +- 集成 4 个 UART,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) - 集成 2 个温度传感器 +### 3.3 E2000Q -### 3.3 E2000D - -- E2000D 1个cluster有2个cpu,共两核。主要技术特征如下: +- E2000Q 集成2个FTC664核和2个FTC310核。主要技术特征如下: - 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA - 支持单精度、双精度浮点运算指令 -- L1有32KB,L2有256KB -- 集成1个DDR4 通道,可对DDR 存储数据进行实时加密 -- 集成4 Lane PCIE3.0 接口(4X1) -- 集成网络接口4x1000M SGMII,1路支持RGMII/RMII,支持1路TSN -- 集成2个USB2.0(OTG)接口 -- 集成1个HDAudio,支持音频输出;2路DP显示接口 +- 两个 FTC664 核各包含 1MB 私有 L2 Cache,由两个 FTC310 核组成的Cluster 内含 256KB 共享的 L2 Cache +- 集成1个DDR4 通道 +- 集成6Lane PCIE3.0 接口(X4+2*X1 、X2+4*X2、6*X1) +- 集成4个1000M以太网控制器,支持2路SGMII接口和2路SGMII/RGMII接口 +- 集成3路USB2.0(OTG)和2路USB3.0(兼容 2.0) - 集成2路SATA3.0模块 -- 集成常用低速接口:WDT,DMAC,QSPI,PWM,Nand,SD/SDIO/eMMC ,SPI_M,UART,I2C,MIO,CAN, LPC_M_S,GPIO,LBC,Timer +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT、QSPI、PWM、Nand、SD/SDIO/eMMC 、SPI_M、UART、I2C、I2S、MIO、CAN-FD、GPIO、LocalBus、Timer -### 3.4 E2000S +### 3.4 E2000D -- E2000S 1个cluster有1个cpu,单核结构。主要技术特征如下: +- E2000D 集成 2 个 FTC310 核。主要技术特征如下: - 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA - 支持单精度、双精度浮点运算指令 -- L1有32KB,L2有256KB -- 集成1个DDR4 通道,可对DDR 存储数据进行实时加密 +- L2 Cache 有256KB +- 集成1个DDR4 通道 +- 集成4 Lane PCIE3.0 接口(4X1) +- 集成4个1000M以太网控制器,支持 2 路 SGMII 接口和 2 路 SGMII/RGMII 接口 +- 集成3路USB2.0(OTG)和2路USB3.0(兼容 2.0) +- 集成2路SATA3.0模块 +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT,QSPI,PWM,Nand,SD/SDIO/eMMC ,SPI_M,UART,I2C,MIO,CAN-FD,GPIO,LocalBus,Timer + +### 3.5 E2000S + +- E2000S 集成 1 个 FTC310 核,单核结构。主要技术特征如下: + +- 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA +- 支持单精度、双精度浮点运算指令 +- L2 Cache 有256KB +- 集成1个DDR4 通道 - 集成2 Lane PCIE3.0 接口(2X1) -- 集成网络接口2x1000M SGMII/RGMII/RMII,支持2路NCSI -- 集成2个USB2.0(OTG)接口 -- 集成1个HDAudio,支持音频输出;2路DP显示接口 -- 集成JPEG Encoder模块 -- 集成常用低速接口:WDT,DMAC,PWM,QSPI,SD/SDIO/eMMC,SPI_M,UART,I2C,MIO,I3C,PMBUS, LPC_M_S,GPIO,oneWire,Timer +- 集成3个1000M以太网控制器,支持1路SGMII接口和2路RGMII/RMII接口 +- 集成1路USB2.0(Device)和2路USB2.0(OTG) +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT、DMAC、PWM、QSPI、SD/SDIO/eMMC、SPI Master、UART、I2C、MIO、I3C、PMBUS、GPIO、SGPIO、One-Wire、Timer、One-Wire ## 4 外设驱动支持情况 @@ -200,6 +221,7 @@ D2000 是一款面向桌面应用的高性能通用 8 核处理器。每 2 个 | OpenAMP | FT2000/4
D2000
E2000 | | openamp | | LittleFS-2.4.2 | | FT2000/4
E2000
D2000 | littlefs-2.4.2 | | SPIFFS-0.3.7 | FT2000/4
D2000
E2000 | | spiffs-0.3.7 | +| freemodbus-v1.6 | E2000 | | protocols/fmodbus_test | --- @@ -241,6 +263,8 @@ D2000 是一款面向桌面应用的高性能通用 8 核处理器。每 2 个 #### 5.1.17 [FSDIO](./doc/reference/driver/fsdio.md) +#### 5.1.18 [FMEDIA](doc/reference/driver/fmedia.md) + ### 5.2 MEMORY #### 5.2.1 [FMEMORY_POOL](./doc/reference/sdk/fmemory_pool.md) @@ -266,6 +290,13 @@ wangxiaodong1030@phytium.com.cn liushengming1118@phytium.com.cn +wangzongqiang1322@phytium.com.cn + +liqiaozhong1404@phytium.com.cn + +liuzhihong1235@phytium.com.cn + +zhangyan1491@phytium.com.cn --- diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/faarch32.h b/bsp/phytium/libraries/standalone/arch/armv8/aarch32/faarch32.h deleted file mode 100644 index 0a7778fad2..0000000000 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/faarch32.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: faarch32.h - * Date: 2022-02-10 14:53:41 - * LastEditTime: 2022-02-17 17:28:37 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 Huanghe 2021/7/3 init - * 1.1 Wangxiaodong 2021/9/24 modify sys_icc_bpr_set and sys_icc_bpr_get - */ - -#ifndef BSP_AARCH32_ASM_H -#define BSP_AARCH32_ASM_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "ftypes.h" - -#define __ASM __asm -#define __STATIC_INLINE static inline -#define __STRINGIFY(x) #x -/* C语言实现MCR指令 */ -#define __MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \ - __ASM volatile("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \ - "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " __STRINGIFY(opcode_2) \ - : \ - : "r"(src) \ - : "memory"); - -/* C语言实现MRC指令 */ -#define __MRC(coproc, opcode_1, CRn, CRm, opcode_2) \ - ( \ - { \ - u32 __dst; \ - __ASM volatile("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \ - "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " __STRINGIFY(opcode_2) \ - : "=r"(__dst)::"memory"); \ - __dst; \ - }) - -/* C语言实现MRRC指令 */ -#define __MRRC(coproc, opcode_1, dst_1, dst_2, CRm) ( \ - { \ - __asm__ __volatile__( \ - "MRRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \ - "%0,%1," __STRINGIFY(c##CRm) \ - : "=r"(dst_1), "=r"(dst_2)); \ - }) - -/** - * @name: aarch32_cntp_ctl_get - * @msg: Read the register that holds the timer value for the EL1 physical timer. - * @return {__STATIC_INLINEu32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer. - */ -__attribute__((always_inline)) __STATIC_INLINE u32 aarch32_cntp_ctl_get(void) -{ - /* MRC p15(coproc) 0(opcode1) CR14(n) CR2(m) 1(opcode2) */ - return __MRC(15, 0, 14, 2, 1); -} - -/** - * @name: aarch32_cntp_tlb_get - * @msg: - * @return {*} - * @param {__STATIC_INLINE u32} aarch32_cntp_ctl_get - */ -__attribute__((always_inline)) __STATIC_INLINE u32 aarch32_cntp_tlb_get(void) -{ - return __MRC(15, 0, 0, 2, 0); -} - -/** - * @name: aarch32_cntp_ctl_set - * @msg: Read the register that holds the timer value for the EL1 physical timer. - * @return {__STATIC_INLINEu32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer. - */ -__attribute__((always_inline)) __STATIC_INLINE void aarch32_cntp_ctl_set(u32 regVal) -{ - /* MRC p15(coproc) regVal 0(opcode1) CR14(n) CR2(m) 1(opcode2) */ - __MCR(15, 0, regVal, 14, 2, 1); -} - -/** - * @name: arm_aarch32_cntfrq_get - * @msg: This register is provided so that software can discover the frequency of the system counter. - * @return {__STATIC_INLINEu32}: frequency of the system counter - */ -__attribute__((always_inline)) __STATIC_INLINE u32 aarch32_cntfrq_get(void) -{ - return __MRC(15, 0, 14, 0, 0); -} - -/** - * @name: aarch32_cntpct_get - * @msg: get the 64-bit physical count value - * @return {*} - * @param {__STATIC_INLINE u64} aarch32_cntpct_get - */ -__attribute__((always_inline)) __STATIC_INLINE u64 aarch32_cntpct_get() -{ - u64 cnt = 0; - u32 cnt_low = 0, cnt_high = 0; - __MRRC(15, 0, cnt_low, cnt_high, 14); - cnt = (u64)cnt_high << 32 | cnt_low; - return cnt; -} - -/** - * @name: aarch32_cntp_tval_set - * @msg: write the register that control register for the EL1 physical timer. - * @in param {u32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer. - */ -__attribute__((always_inline)) __STATIC_INLINE void aarch32_cntp_tval_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 2, 0); -} - -/** - * @name: aarch32_sctrl_get - * @msg: read the register that control system - */ -__attribute__((always_inline)) __STATIC_INLINE u32 aarch32_sctrl_get() -{ - return __MRC(15, 0, 1, 0, 0); -} - -/** - * @name: aarch32_sctrl_set - * @msg: read the register that control system - */ -#define AARCH32_SCTRL_CACHE_BIT (1 << 2) /* 1: enable, 0: disable */ -__attribute__((always_inline)) __STATIC_INLINE void aarch32_sctrl_set(u32 RegVal) -{ - __MCR(15, 0, RegVal, 1, 0, 0); -} - -/**********************************************/ - -__attribute__((always_inline)) __STATIC_INLINE u32 __get_VBAR(void) -{ - return __MRC(15, 0, 12, 0, 0); -} - -__attribute__((always_inline)) __STATIC_INLINE void __set_VBAR(u32 vbar) -{ - __MCR(15, 0, vbar, 12, 0, 0); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_igrpen0_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 6); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_igrpen0_get(void) -{ - return __MRC(15, 0, 12, 12, 6); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_igrpen1_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 7); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_igrpen1_get(void) -{ - return __MRC(15, 0, 12, 12, 7); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_ctlr_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 4); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_ctlr_get(void) -{ - return __MRC(15, 0, 12, 12, 4); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_hppir0_get(void) -{ - return __MRC(15, 0, 12, 8, 2); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_bpr_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 3); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_bpr_get(void) -{ - return __MRC(15, 0, 12, 12, 3); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_hppir1_get(void) -{ - return __MRC(15, 0, 12, 12, 2); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_eoir0_set(u32 value) -{ - __MCR(15, 0, value, 12, 8, 1); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_eoir1_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 1); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_pmr_set(u32 value) -{ - __MCR(15, 0, value, 4, 6, 0); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_pmr_get(void) -{ - return __MRC(15, 0, 4, 6, 0); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_iar1_get(void) -{ - return __MRC(15, 0, 12, 12, 0); -} - -__attribute__((always_inline)) __STATIC_INLINE void sys_icc_sre_set(u32 value) -{ - __MCR(15, 0, value, 12, 12, 5); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_sre_get(void) -{ - return __MRC(15, 0, 12, 12, 5); -} - -__attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_rpr_get(void) -{ - return __MRC(15, 0, 12, 11, 3); -} - -/* Generic Timer registers */ -/** - * @name: arm_aarch32_cntfrq_get - * @msg: This register is provided so that software can discover the frequency of the system counter. - * @return {__STATIC_INLINEu32}: frequency of the system counter - */ -__attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntfrq_get(void) -{ - return __MRC(15, 0, 14, 0, 0); -} - -/* arm_aarch32_cnttimer_set */ -__attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cnttimer_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 2, 2); -} - -/** - * @name: arm_aarch32_cnthv_tval_get - * @msg: Provides AArch32 access to the timer value for the EL2 virtual timer. - * @return {__STATIC_INLINEu32}: EL2 virtual timer Cnt. - */ -__attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cnthv_tval_get(void) -{ - return __MRC(15, 0, 14, 3, 0); -} - -/** - * @name: arm_aarch32_cnthv_ctl_set - * @msg: Provides AArch32 access to the control register for the EL2 virtual timer. - * @in param {u32}: RegValue;ENABLE: bit [0] 0 Timer disabled,1 Timer enabled. - * IMASK,bit [1]: 0 Timer interrupt is not masked by the IMASK bit. 1 Timer interrupt is masked by the IMASK bit. - * ISTATUS, bit [2]: 0 Timer condition is not met. 1 Timer condition is met. rea-only - */ -__attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cnthv_ctl_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 3, 1); -} - -/** - * @name: arm_aarch32_cnthv_ctl_get - * @msg: Provides AArch32 access to the control register for the EL2 virtual timer. - * @return {__STATIC_INLINEu32}: RegValue;ENABLE: bit [0] 0 Timer disabled,1 Timer enabled. - * IMASK,bit [1]: 0 Timer interrupt is not masked by the IMASK bit. 1 Timer interrupt is masked by the IMASK bit. - * ISTATUS, bit [2]: 0 Timer condition is not met. 1 Timer condition is met. read-only - */ -__attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cnthv_ctl_get(void) -{ - return __MRC(15, 0, 14, 3, 1); -} - -/** - * @name: arm_aarch32_cnthv_tval_set - * @msg: Provides AArch32 access to the timer value for the EL2 virtual timer. - * @in param {u32}: TimerValue, bits [31:0] The TimerValue view of the EL2 virtual timer. - */ -__attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cnthv_tval_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 3, 0); -} - -/** - * @name: arm_aarch32_cntvct_get - * @msg: Read the register that holds the 64-bit virtual count value. The virtual count value is equal to the physical count value visible in CNTPCT minus the virtual offset visible in CNTVOFF. - * @return {__STATIC_INLINEu64}Bits [63:0] Virtual count value. - */ -__attribute__((always_inline)) __STATIC_INLINE u64 arm_aarch32_cntvct_get(void) -{ - /* "r0" --- low, - "r1" --- hi - */ - u32 low; - u32 hi; - __asm__ volatile( - ".word 0xec510f1e \n" /* mrrc p15, 1, r0, r1, c14 */ - "mov %0, r0 \n" - "mov %1, r1 \n" - : "=&r"(low), "=&r"(hi)); - return (((u64)hi) << 32) | low; -} - -/* physical */ - -/** - * @name: arm_aarch32_cntp_tval_get - * @msg: Read the register that holds the timer value for the EL1 physical timer. - * @return {__STATIC_INLINEu32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer. - */ -__attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntp_tval_get(void) -{ - return __MRC(15, 0, 14, 2, 0); -} - -/** - * @name: arm_aarch32_cntp_tval_set - * @msg: write the register that control register for the EL1 physical timer. - * @in param {u32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer. - */ -__attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cntp_tval_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 2, 0); -} - -/** - * @name: arm_aarch32_cntp_ctl_set - * @msg: write the register that control register for the EL1 physical timer. - * @in param {u32}: ENABLE, bit[0] Enables the timer ; IMASK, bit [1] Timer interrupt mask bit; ISTATUS, bit [2] The status of the timer. - */ -__attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cntp_ctl_set(u32 RegValue) -{ - __MCR(15, 0, RegValue, 14, 2, 1); -} - -/** - * @name: arm_aarch32_cntp_ctl_get - * @msg: Read the register that control register for the EL1 physical timer. - * @return {__STATIC_INLINEu32}: ENABLE, bit[0] Enables the timer ; IMASK, bit [1] Timer interrupt mask bit; ISTATUS, bit [2] The status of the timer. - */ -__attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntp_ctl_get(void) -{ - return __MRC(15, 0, 14, 2, 1); -} - -/** - * @name: arm_aarch32_cntpct_get - * @msg: Read the register that holds the 64-bit physical count value. - * @return {__STATIC_INLINEu64} CompareValue, bits [63:0] Physical count value. - */ -__attribute__((always_inline)) __STATIC_INLINE u64 arm_aarch32_cntpct_get(void) -{ - /* "r0" --- low, - "r1" --- hi - */ - u32 low; - u32 hi; - __asm__ volatile( - - ".word 0xec510f0e \n" /* mrrc p15, 0, r0, r1, c14 */ - "mov %0, r0 \n" - "mov %1, r1 \n" - : "=&r"(low), "=&r"(hi)); - return (((u64)hi) << 32) | low; -} - -#define INTERRUPT_DISABLE() \ - __asm volatile("CPSID i" :: \ - : "memory"); \ - __asm volatile("DSB"); \ - __asm volatile("ISB"); - -#define INTERRUPT_ENABLE() \ - __asm volatile("CPSIE i" :: \ - : "memory"); \ - __asm volatile("DSB"); \ - __asm volatile("ISB"); - -#ifdef __cplusplus -} -#endif - -#endif // ! \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.c b/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.c deleted file mode 100644 index 082a74eb4e..0000000000 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: generic_timer.c - * Date: 2022-02-10 14:53:41 - * LastEditTime: 2022-02-17 17:30:07 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - */ - - -#include "fparameters.h" -#include "fgeneric_timer.h" -#include "faarch32.h" -#include "sdkconfig.h" - -#ifndef SDK_CONFIG_H__ - #warning "Please include sdkconfig.h" -#endif - -#ifdef CONFIG_USE_SYS_TICK - #include "fassert.h" - #include "finterrupt.h" - - static volatile u32 genericTick; - static GenericTimerTickHandler usr_tick_handler = NULL; -#endif - -#define AARCH32_CNTP_CTL_ENABLE_MASK (1ul << 0) -#define AARCH32_CNTP_CTL_INTERRUPT_MASK (1ul << 1) - -void GenericTimerStart(void) -{ - u32 ctrl = aarch32_cntp_ctl_get(); - - if (!(ctrl & AARCH32_CNTP_CTL_ENABLE_MASK)) - { - ctrl |= AARCH32_CNTP_CTL_ENABLE_MASK; - aarch32_cntp_ctl_set(ctrl); - } -} - -void GenericTimerStop(void) -{ - u32 ctrl = aarch32_cntp_ctl_get(); - if ((ctrl & AARCH32_CNTP_CTL_ENABLE_MASK)) - { - ctrl &= ~AARCH32_CNTP_CTL_ENABLE_MASK; - aarch32_cntp_ctl_set(ctrl); - } -} - -void GenericTimerInterruptEnable(void) -{ - u32 ctrl = aarch32_cntp_ctl_get(); - if (ctrl & AARCH32_CNTP_CTL_INTERRUPT_MASK) - { - ctrl &= ~AARCH32_CNTP_CTL_INTERRUPT_MASK; - aarch32_cntp_ctl_set(ctrl); - } -} - -void GenericTimerInterruptDisable(void) -{ - u64 ctrl = aarch32_cntp_ctl_get(); - if (!(ctrl & AARCH32_CNTP_CTL_INTERRUPT_MASK)) - { - ctrl |= AARCH32_CNTP_CTL_INTERRUPT_MASK; - aarch32_cntp_ctl_set(ctrl); - } -} - -u32 GenericTimerFrequecy(void) -{ - u32 rate = aarch32_cntfrq_get(); - return (rate != 0) ? rate : 1000000; -} - -u64 GenericTimerRead(void) -{ - return aarch32_cntpct_get(); -} - -void GenericTimerCompare(u32 interval) -{ - aarch32_cntp_tval_set(interval); -} - -#ifdef CONFIG_USE_SYS_TICK -static void GenericTimerClearTickIntr(u32 tickRateHz) -{ - GenericTimerCompare(GenericTimerFrequecy() / tickRateHz); -} - -static void GenericTimerTickIntrHandler(s32 vector, void *param) -{ - u32 tickRateHz = (u32)param; - (void)vector; - genericTick++; /* tick */ - GenericTimerClearTickIntr(tickRateHz); /* clear tick intrrupt */ - - if (usr_tick_handler) /* execute user handler */ - usr_tick_handler(); -} -#endif - -void GenericTimerSetupSystick(u32 tickRateHz, GenericTimerTickHandler tickHandler, u32 intrPrority) -{ -#ifdef CONFIG_USE_SYS_TICK - u32 cntFrq; - - /* disable timer and get system frequency */ - GenericTimerStop(); - cntFrq = GenericTimerFrequecy(); - - /* set tick rate */ - GenericTimerCompare(cntFrq / tickRateHz); - GenericTimerInterruptEnable(); - - /* set generic timer intrrupt */ - InterruptSetPriority(GENERIC_TIMER_NS_IRQ_NUM, intrPrority); - - /* install tick handler */ - usr_tick_handler = tickHandler; - InterruptInstall(GENERIC_TIMER_NS_IRQ_NUM, GenericTimerTickIntrHandler, - (void *)tickRateHz, "GenericTimerTick"); - - /* enable intrrupt */ - InterruptUmask(GENERIC_TIMER_NS_IRQ_NUM); - GenericTimerStart(); -#endif -} - -u32 GenericGetTick(void) -{ -#ifdef CONFIG_USE_SYS_TICK - return genericTick; -#else - return 0xffU; -#endif -} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/Kconfig b/bsp/phytium/libraries/standalone/board/Kconfig index f0a7ec4b70..5169f3e1e2 100644 --- a/bsp/phytium/libraries/standalone/board/Kconfig +++ b/bsp/phytium/libraries/standalone/board/Kconfig @@ -11,19 +11,22 @@ menu "Board Configuration" config TARGET_D2000 bool "D2000" - + config TARGET_E2000Q bool "E2000Q" select TARGET_E2000 - + config TARGET_E2000D bool "E2000D" select TARGET_E2000 - + config TARGET_E2000S bool "E2000S" select TARGET_E2000 +# config TARGET_TARDIGRADE +# bool "TARDIGRADE" + endchoice # BUILD_TARGET_CHIP_TYPE # an invisible config to define common code of E2000 Q/D/S @@ -43,7 +46,7 @@ menu "Board Configuration" config DEFAULT_DEBUG_PRINT_UART2 bool "Use uart2" endchoice # DEBUG_PRINT_UART - + endmenu diff --git a/bsp/phytium/libraries/standalone/board/common/fcpu_asm.S b/bsp/phytium/libraries/standalone/board/common/fcpu_asm.S index 530186fecf..c536bef925 100644 --- a/bsp/phytium/libraries/standalone/board/common/fcpu_asm.S +++ b/bsp/phytium/libraries/standalone/board/common/fcpu_asm.S @@ -14,7 +14,7 @@ * FilePath: _cpu_asm.S * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-17 17:57:55 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/board/common/fcpu_info.c b/bsp/phytium/libraries/standalone/board/common/fcpu_info.c index 7e711e2018..9b7c718ace 100644 --- a/bsp/phytium/libraries/standalone/board/common/fcpu_info.c +++ b/bsp/phytium/libraries/standalone/board/common/fcpu_info.c @@ -34,48 +34,48 @@ FError GetCpuId(u32 *cpu_id_p) switch (affinity & 0xfff) { #ifdef CORE0_AFF - case CORE0_AFF: - *cpu_id_p = 0 ; - break; + case CORE0_AFF: + *cpu_id_p = 0 ; + break; #endif #ifdef CORE1_AFF - case CORE1_AFF: - *cpu_id_p = 1 ; - break; + case CORE1_AFF: + *cpu_id_p = 1 ; + break; #endif #ifdef CORE2_AFF - case CORE2_AFF: - *cpu_id_p = 2; - break; + case CORE2_AFF: + *cpu_id_p = 2; + break; #endif #ifdef CORE3_AFF - case CORE3_AFF: - *cpu_id_p = 3 ; - break; + case CORE3_AFF: + *cpu_id_p = 3 ; + break; #endif #ifdef CORE4_AFF - case CORE4_AFF: - *cpu_id_p = 4 ; - break; + case CORE4_AFF: + *cpu_id_p = 4 ; + break; #endif #ifdef CORE5_AFF - case CORE5_AFF: - *cpu_id_p = 5 ; - break; + case CORE5_AFF: + *cpu_id_p = 5 ; + break; #endif #ifdef CORE6_AFF - case CORE6_AFF: - *cpu_id_p = 6 ; - break; + case CORE6_AFF: + *cpu_id_p = 6 ; + break; #endif #ifdef CORE7_AFF - case CORE7_AFF: - *cpu_id_p = 7 ; - break; + case CORE7_AFF: + *cpu_id_p = 7 ; + break; #endif - default: - ret = ERR_GENERAL ; - break; + default: + ret = ERR_GENERAL ; + break; } return ret; } @@ -95,48 +95,48 @@ FError GetCpuAffinityByMask(u32 cpu_id_mask, u64 *affinity_level_p) switch (cpu_id_mask) { #ifdef CORE0_AFF - case (1<<0): - *affinity_level_p = CORE0_AFF; - break ; + case (1<<0): + *affinity_level_p = CORE0_AFF; + break ; #endif #ifdef CORE1_AFF - case (1<<1): - *affinity_level_p = CORE1_AFF; - break ; + case (1<<1): + *affinity_level_p = CORE1_AFF; + break ; #endif #ifdef CORE2_AFF - case (1<<2): - *affinity_level_p = CORE2_AFF; - break ; + case (1<<2): + *affinity_level_p = CORE2_AFF; + break ; #endif #ifdef CORE3_AFF - case (1<<3): - *affinity_level_p = CORE3_AFF; - break ; + case (1<<3): + *affinity_level_p = CORE3_AFF; + break ; #endif #ifdef CORE4_AFF - case (1<<4): - *affinity_level_p = CORE4_AFF; - break ; + case (1<<4): + *affinity_level_p = CORE4_AFF; + break ; #endif #ifdef CORE5_AFF - case (1<<5): - *affinity_level_p = CORE5_AFF; - break ; + case (1<<5): + *affinity_level_p = CORE5_AFF; + break ; #endif #ifdef CORE6_AFF - case (1<<6): - *affinity_level_p = CORE6_AFF; - break ; + case (1<<6): + *affinity_level_p = CORE6_AFF; + break ; #endif #ifdef CORE7_AFF - case (1<<7): - *affinity_level_p = CORE7_AFF; - break ; + case (1<<7): + *affinity_level_p = CORE7_AFF; + break ; #endif - default: - ret = ERR_GENERAL; - break; + default: + ret = ERR_GENERAL; + break; } return ret; } @@ -157,48 +157,48 @@ FError GetCpuAffinity(u32 cpu_id, u64 *affinity_level_p) switch (cpu_id) { #ifdef CORE0_AFF - case (0): - *affinity_level_p = CORE0_AFF; - break ; + case (0): + *affinity_level_p = CORE0_AFF; + break ; #endif #ifdef CORE1_AFF - case (1): - *affinity_level_p = CORE1_AFF; - break ; + case (1): + *affinity_level_p = CORE1_AFF; + break ; #endif #ifdef CORE2_AFF - case (2): - *affinity_level_p = CORE2_AFF; - break ; + case (2): + *affinity_level_p = CORE2_AFF; + break ; #endif #ifdef CORE3_AFF - case (3): - *affinity_level_p = CORE3_AFF; - break ; + case (3): + *affinity_level_p = CORE3_AFF; + break ; #endif #ifdef CORE4_AFF - case (4): - *affinity_level_p = CORE4_AFF; - break ; + case (4): + *affinity_level_p = CORE4_AFF; + break ; #endif #ifdef CORE5_AFF - case (5): - *affinity_level_p = CORE5_AFF; - break ; + case (5): + *affinity_level_p = CORE5_AFF; + break ; #endif #ifdef CORE6_AFF - case (6): - *affinity_level_p = CORE6_AFF; - break ; + case (6): + *affinity_level_p = CORE6_AFF; + break ; #endif #ifdef CORE7_AFF - case (7): - *affinity_level_p = CORE7_AFF; - break ; + case (7): + *affinity_level_p = CORE7_AFF; + break ; #endif - default: - ret = ERR_GENERAL; - break; + default: + ret = ERR_GENERAL; + break; } return ret; } @@ -217,48 +217,48 @@ FError UseAffinityGetCpuId(u64 affinity_level, u32 *cpu_id_p) switch (affinity_level) { #ifdef CORE0_AFF - case CORE0_AFF: - *cpu_id_p = 0; - break ; + case CORE0_AFF: + *cpu_id_p = 0; + break ; #endif #ifdef CORE1_AFF - case CORE1_AFF: - *cpu_id_p = 1; - break ; + case CORE1_AFF: + *cpu_id_p = 1; + break ; #endif #ifdef CORE2_AFF - case CORE2_AFF: - *cpu_id_p = 2; - break ; + case CORE2_AFF: + *cpu_id_p = 2; + break ; #endif #ifdef CORE3_AFF - case CORE3_AFF: - *cpu_id_p = 3; - break ; + case CORE3_AFF: + *cpu_id_p = 3; + break ; #endif #ifdef CORE4_AFF - case CORE4_AFF: - *cpu_id_p = 4; - break ; + case CORE4_AFF: + *cpu_id_p = 4; + break ; #endif #ifdef CORE5_AFF - case CORE5_AFF: - *cpu_id_p = 5; - break ; + case CORE5_AFF: + *cpu_id_p = 5; + break ; #endif #ifdef CORE6_AFF - case CORE6_AFF: - *cpu_id_p = 6; - break ; + case CORE6_AFF: + *cpu_id_p = 6; + break ; #endif #ifdef CORE7_AFF - case CORE7_AFF: - *cpu_id_p = 7; - break ; + case CORE7_AFF: + *cpu_id_p = 7; + break ; #endif - default: - ret = ERR_GENERAL; - break; + default: + ret = ERR_GENERAL; + break; } return ret; } diff --git a/bsp/phytium/libraries/standalone/board/e2000/fearly_uart.c b/bsp/phytium/libraries/standalone/board/common/fearly_uart.c similarity index 98% rename from bsp/phytium/libraries/standalone/board/e2000/fearly_uart.c rename to bsp/phytium/libraries/standalone/board/common/fearly_uart.c index a330aa37b3..7d114ceac9 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/fearly_uart.c +++ b/bsp/phytium/libraries/standalone/board/common/fearly_uart.c @@ -14,7 +14,7 @@ * FilePath: early_uart.c * Date: 2022-02-11 13:33:28 * LastEditTime: 2022-02-17 17:59:26 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/board/e2000/fearly_uart.h b/bsp/phytium/libraries/standalone/board/common/fearly_uart.h similarity index 96% rename from bsp/phytium/libraries/standalone/board/e2000/fearly_uart.h rename to bsp/phytium/libraries/standalone/board/common/fearly_uart.h index cbb47a898f..d156804867 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/fearly_uart.h +++ b/bsp/phytium/libraries/standalone/board/common/fearly_uart.h @@ -14,15 +14,15 @@ * FilePath: fearly_uart.h * Date: 2022-02-11 13:33:28 * LastEditTime: 2022-02-17 18:00:16 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 rtos 2022/6/25 init commit */ -#ifndef BOARD_E2000_EARLY_UART_H -#define BOARD_E2000_EARLY_UART_H +#ifndef BOARD_COMMON_EARLY_UART_H +#define BOARD_COMMON_EARLY_UART_H #ifdef __cplusplus extern "C" diff --git a/bsp/phytium/libraries/standalone/board/d2000/fioctrl.c b/bsp/phytium/libraries/standalone/board/d2000/fioctrl.c new file mode 100644 index 0000000000..ae1ff0d3a2 --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/d2000/fioctrl.c @@ -0,0 +1,406 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fioctrl.c + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-18 08:25:29 + * Description:  This files is for io-ctrl function implementation (io-mux/io-config/io-delay) + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/2/22 init commit + */ + + +/***************************** Include Files *********************************/ +#include "fparameters.h" +#include "fio.h" +#include "fkernel.h" +#include "fassert.h" +#include "fdebug.h" + +#include "fioctrl.h" +#include "fpinctrl.h" + +/************************** Constant Definitions *****************************/ +/* Bit[0] : 输入延迟功能使能 */ +#define FIOCTRL_DELAY_EN(delay_beg) BIT(delay_beg) +#define FIOCTRL_INPUT_DELAY_OFF 0 + +/* Bit[3:1] : 输入延迟精调档位选择 */ +#define FIOCTRL_DELICATE_DELAY_MASK(delay_beg) GENMASK((delay_beg + 3), (delay_beg + 1)) +#define FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 3), (delay_beg + 1)) +#define FIOCTRL_DELICATE_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 3), (delay_beg + 1)) + +/* Bit[6:4] : 输入延迟粗调档位选择 */ +#define FIOCTRL_ROUGH_DELAY_MASK(delay_beg) GENMASK((delay_beg + 6), (delay_beg + 4)) +#define FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 6), (delay_beg + 4)) +#define FIOCTRL_ROUGH_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 6), (delay_beg + 4)) + +/* Bit[7] : 保留 */ +/* Bit[8] : 输出延迟功能使能 */ + +/* Bit[11:9] : 输出延迟精调档位选择 */ +/* Bit [14:12] : 输出延迟粗调档位选择 */ +/* Bit [15] : 保留 */ + +#define FIOCTRL_FUNC_BEG_OFF(reg_bit) ((reg_bit) + 0) +#define FIOCTRL_FUNC_END_OFF(reg_bit) ((reg_bit) + 1) /* bit[1:0] 复用功能占2个位 */ +#define FIOCTRL_PULL_BEG_OFF(reg_bit) ((reg_bit) + 2) +#define FIOCTRL_PULL_END_OFF(reg_bit) ((reg_bit) + 3) /* bit[3:2] 上下拉功能占2个位 */ + +#define FIOCTRL_DELAY_IN_BEG_OFF(reg_bit) ((reg_bit) + 0) +#define FIOCTRL_DELAY_IN_END_OFF(reg_bit) ((reg_bit) + 7) /* bit[8:1] 输入延时占7个位 */ +#define FIOCTRL_DELAY_OUT_BEG_OFF(reg_bit) ((reg_bit) + 8) +#define FIOCTRL_DELAY_OUT_END_OFF(reg_bit) ((reg_bit) + 15) /* bit[15:9] 输出延时占7个位 */ + +/* 芯片引脚控制寄存器的起止位置 */ +#define FIOCTRL_REG_OFFSET_MIN 0x200 +#define FIOCTRL_REG_OFFSET_MAX 0x22c + +/* 芯片引脚延时寄存器的起止位置 */ +#define FIOCTRL_DELAY_REG_OFFSET_MIN 0x400 +#define FIOCTRL_DELAY_REG_OFFSET_MAX 0x404 + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FIOCTRL_DEBUG_TAG "FIOCTRL" +#define FIOCTRL_ERROR(format, ...) FT_DEBUG_PRINT_E(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_WARN(format, ...) FT_DEBUG_PRINT_W(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_INFO(format, ...) FT_DEBUG_PRINT_I(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_DEBUG(format, ...) FT_DEBUG_PRINT_D(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) + +#define FIOCTRL_ASSERT_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_REG_OFFSET_MAX)), "invalid pin register off @%d", (pin.reg_off)) +#define FIOCTRL_ASSERT_FUNC(func) FASSERT_MSG((func < FPIN_NUM_OF_FUNC), "invalid func as %d", (func)) +#define FIOCTRL_ASSERT_PULL(pull) FASSERT_MSG((pull < FPIN_NUM_OF_PULL), "invalid pull as %d", (pull)) + +#define FIOCTRL_ASSERT_DELAY_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_DELAY_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_DELAY_REG_OFFSET_MAX)), "invalid delay pin register off @%d", (pin.reg_off)) +#define FIOCTRL_ASSERT_DELAY(delay) FASSERT_MSG(((delay) < FPIN_NUM_OF_DELAY), "invalid delay as %d", (delay)); +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ + +/** + * @name: FPinGetFunc + * @msg: 获取IO引脚当前的复用功能 + * @return {FPinFunc} 当前的复用功能 + * @param {FPinIndex} pin IO引脚索引 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +FPinFunc FPinGetFunc(const FPinIndex pin) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 func = GET_REG32_BITS(reg_val, func_end, func_beg); + FIOCTRL_ASSERT_FUNC(func); + + return (FPinFunc)GET_REG32_BITS(reg_val, func_end, func_beg); +} + +/** + * @name: FPinSetFunc + * @msg: 设置IO引脚复用功能 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinFunc} func IO复用功能 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +void FPinSetFunc(const FPinIndex pin, FPinFunc func) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + FIOCTRL_ASSERT_FUNC(func); + + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + reg_val &= ~GENMASK(func_end, func_beg); + reg_val |= SET_REG32_BITS(func, func_end, func_beg); + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinGetPull + * @msg: 获取IO引脚当前的上下拉设置 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +FPinPull FPinGetPull(const FPinIndex pin) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 pull = GET_REG32_BITS(reg_val, pull_end, pull_beg); + + FIOCTRL_ASSERT_PULL(pull); + return (FPinPull)pull; +} + +/** + * @name: FPinSetPull + * @msg: 设置IO引脚当前的上下拉 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinPull} pull 上下拉设置 + */ +void FPinSetPull(const FPinIndex pin, FPinPull pull) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + FIOCTRL_ASSERT_PULL(pull); + + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + reg_val &= ~GENMASK(pull_end, pull_beg); + reg_val |= SET_REG32_BITS(pull, pull_end, pull_beg); + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinGetConfig + * @msg: 获取IO引脚的复用、上下拉和驱动能力设置 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinFunc} *func IO复用功能 + * @param {FPinPull} *pull pull 上下拉设置 + */ +void FPinGetConfig(const FPinIndex pin, FPinFunc *func, FPinPull *pull) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + if (func) + { + *func = GET_REG32_BITS(reg_val, func_end, func_beg); + } + + if (pull) + { + *pull = GET_REG32_BITS(reg_val, pull_end, pull_beg); + } + + return; +} + +/** + * @name: FPinSetConfig + * @msg: 设置IO引脚的复用、上下拉和驱动能力 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinFunc} func IO复用功能 + * @param {FPinPull} pull pull 上下拉设置 + */ +void FPinSetConfig(const FPinIndex pin, FPinFunc func, FPinPull pull) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + reg_val &= ~GENMASK(func_end, func_beg); + reg_val |= SET_REG32_BITS(func, func_end, func_beg); + + reg_val &= ~GENMASK(pull_end, pull_beg); + reg_val |= SET_REG32_BITS(pull, pull_end, pull_beg); + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinGetDelay + * @msg: 获取IO引脚当前的延时设置 + * @return {FPinDelay} 当前的延时设置 + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {FPinDelayType} type 精调/粗调延时 + */ +FPinDelay FPinGetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + u8 delay = 0; + const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FPIN_DELAY_FINE_TUNING == type) + { + delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg); + } + else if (FPIN_DELAY_COARSE_TUNING == type) + { + delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg); + } + else + { + FASSERT(0); + } + + FIOCTRL_ASSERT_DELAY(delay); + return (FPinDelay)delay; +} + + +/** + * @name: FPinGetDelayEn + * @msg: 获取IO引脚当前的延时使能标志位 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + */ +boolean FPinGetDelayEn(const FPinIndex pin, FPinDelayDir dir) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + boolean enabled = FALSE; + const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FIOCTRL_DELAY_EN(delay_beg) & reg_val) + { + enabled = TRUE; + } + + return enabled; +} + +/** + * @name: FPinSetDelay + * @msg: 设置IO引脚延时 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {FPinDelayType} type 精调/粗调延时 + * @param {FPinDelay} delay 延时档位设置 0 ~ 8 档可用 + */ +void FPinSetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type, FPinDelay delay) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + FIOCTRL_ASSERT_DELAY(delay); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FPIN_DELAY_FINE_TUNING == type) + { + reg_val &= ~FIOCTRL_DELICATE_DELAY_MASK(delay_beg); + delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg); + } + else if (FPIN_DELAY_COARSE_TUNING == type) + { + reg_val &= ~FIOCTRL_ROUGH_DELAY_MASK(delay_beg); + delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg); + } + else + { + FASSERT(0); + } + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinSetDelayEn + * @msg: 使能/去使能IO引脚延时 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {boolean} enable TRUE: 使能, FALSE: 去使能 + */ +void FPinSetDelayEn(const FPinIndex pin, FPinDelayDir dir, boolean enable) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + reg_val &= ~FIOCTRL_DELAY_EN(delay_beg); + if (enable) + { + reg_val |= FIOCTRL_DELAY_EN(delay_beg); + } + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/d2000/fioctrl.h b/bsp/phytium/libraries/standalone/board/d2000/fioctrl.h new file mode 100644 index 0000000000..9012e7d2ab --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/d2000/fioctrl.h @@ -0,0 +1,83 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fioctrl.h + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-18 08:25:35 + * Description:  This files is for io-ctrl function definition (io-mux/io-config/io-delay) + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/2/22 init commit + */ + + +#ifndef BOARD_D2000_FIOCTRL_H +#define BOARD_D2000_FIOCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************** Include Files *********************************/ +#include "ftypes.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FIOCTRL_INDEX(offset, func_beg) \ + { \ + /* reg_off */ (offset), \ + /* reg_bit */ (func_beg) \ + } + +/************************** Variable Definitions *****************************/ +#define FIOCTRL_CRU_CLK_OBV_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 24) +#define FIOCTRL_SPI0_CSN0_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 16) +#define FIOCTRL_SPI0_SCK_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 12) +#define FIOCTRL_SPI0_SO_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 8) +#define FIOCTRL_SPI0_SI_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 4) + +#define FIOCTRL_TJTAG_TDI_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 24) /* can0-tx: func 1 */ +#define FIOCTRL_SWDITMS_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 12) /* can0-rx: func 1 */ + +#define FIOCTRL_NTRST_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 20) /* can1-tx: func 1 */ +#define FIOCTRL_SWDO_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 8) /* can1-rx: func 1 */ + +#define FIOCTRL_I2C0_SCL_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 24) /* i2c0-scl: func 0 */ +#define FIOCTRL_I2C0_SDA_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 20) /* i2c0-sda: func 0 */ +#define FIOCTRL_ALL_PLL_LOCK_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 28) /* i2c1-scl: func 2 */ +#define FIOCTRL_CRU_CLK_OBV_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 24) /* i2c1-sda: func 2 */ +#define FIOCTRL_SWDO_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 8) /* i2c2-scl: func 2 */ +#define FIOCTRL_TDO_SWJ_IN_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 4) /* i2c2-sda: func 2 */ +#define FIOCTRL_HDT_MB_DONE_STATE_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 0) /* i2c3-scl: func 2 */ +#define FIOCTRL_HDT_MB_FAIL_STATE_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 28) /* i2c3-sda: func 2 */ + +#define FIOCTRL_UART_2_RXD_PAD (FPinIndex)FIOCTRL_INDEX(0x210, 0) /* spi1_csn0: func 1 */ +#define FIOCTRL_UART_2_TXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 28) /* spi1_sck: func 1 */ +#define FIOCTRL_UART_3_RXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 24) /* spi1_so: func 1 */ +#define FIOCTRL_UART_3_TXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 20) /* spi1_si: func 1 */ +#define FIOCTRL_QSPI_CSN2_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 8) /* spi1_csn1: func 1 */ +#define FIOCTRL_QSPI_CSN3_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 4) /* spi1_csn2: func 1 */ + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/phytium/libraries/standalone/board/d2000/fparameters.h b/bsp/phytium/libraries/standalone/board/d2000/fparameters.h new file mode 100644 index 0000000000..e848dfa90d --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/d2000/fparameters.h @@ -0,0 +1,347 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fparameters.h + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-17 17:58:51 + * Description:  This file is for + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + */ + +#ifndef BSP_BOARD_D2000_PARAMETERS_H +#define BSP_BOARD_D2000_PARAMETERS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__ASSEMBLER__) +#include "ftypes.h" +#endif + +#define CORE0_AFF 0x0 +#define CORE1_AFF 0x1 +#define CORE2_AFF 0x100 +#define CORE3_AFF 0x101 +#define CORE4_AFF 0x200 +#define CORE5_AFF 0x201 +#define CORE6_AFF 0x300 +#define CORE7_AFF 0x301 + +/* cache */ +#define CACHE_LINE_ADDR_MASK 0x3F +#define CACHE_LINE 64U + +/* Device register address */ +#define FDEV_BASE_ADDR 0x28000000 +#define FDEV_END_ADDR 0x2FFFFFFF + +/* Generic Timer */ +#define GENERIC_TIMER_NS_IRQ_NUM 30 + +/* PCI */ + +#define FPCIE_NUM 1 +#define FPCIE0_ID 0 +#define FPCIE0_MISC_IRQ_NUM 59 + +#define FPCIE_CFG_MAX_NUM_OF_BUS 256 +#define FPCIE_CFG_MAX_NUM_OF_DEV 32 +#define FPCIE_CFG_MAX_NUM_OF_FUN 8 + +#define FPCI_CONFIG_BASE_ADDR 0x40000000 +#define FPCI_CONFIG_REG_LENGTH 0x10000000 + +#define FPCI_IO_CONFIG_BASE_ADDR 0x50000000 +#define FPCI_IO_CONFIG_REG_LENGTH 0x08000000 + +#define FPCI_MEM32_BASE_ADDR 0x58000000 +#define FPCI_MEM32_REG_LENGTH 0x27ffffff + +#define FPCI_MEM64_BASE_ADDR 0x1000000000 +#define FPCI_MEM64_REG_LENGTH 0x1000000000 + +#define FPCI_EU0_C0_CONTROL_BASE_ADDR 0x29900000 +#define FPCI_EU0_C1_CONTROL_BASE_ADDR 0x29910000 +#define FPCI_EU0_C2_CONTROL_BASE_ADDR 0x29920000 +#define FPCI_EU1_C0_CONTROL_BASE_ADDR 0x29930000 +#define FPCI_EU1_C1_CONTROL_BASE_ADDR 0x29940000 +#define FPCI_EU1_C2_CONTROL_BASE_ADDR 0x29950000 + +#define FPCI_EU0_CONFIG_BASE_ADDR 0x29900000 +#define FPCI_EU1_CONFIG_BASE_ADDR 0x299A0000 + + +#define FPCI_INTA_IRQ_NUM 60 +#define FPCI_INTB_IRQ_NUM 61 +#define FPCI_INTC_IRQ_NUM 62 +#define FPCI_INTD_IRQ_NUM 63 + +#define FPCI_NEED_SKIP 0 + +#define FPCI_INTX_EOI +#define FPCI_INTX_PEU0_STAT 0x29100000 +#define FPCI_INTX_PEU1_STAT 0x29101000 + +#define FPCI_INTX_EU0_C0_CONTROL 0x29000184 +#define FPCI_INTX_EU0_C1_CONTROL 0x29010184 +#define FPCI_INTX_EU0_C2_CONTROL 0x29020184 +#define FPCI_INTX_EU1_C0_CONTROL 0x29030184 +#define FPCI_INTX_EU1_C1_CONTROL 0x29040184 +#define FPCI_INTX_EU1_C2_CONTROL 0x29050184 + +#define FPCI_INTX_CONTROL_NUM 6 /* Total number of controllers */ +#define FPCI_INTX_SATA_NUM 2 /* Total number of controllers */ + +/* platform ahci host */ +#define PLAT_AHCI_HOST_MAX_COUNT 5 +#define AHCI_BASE_0 0 +#define AHCI_BASE_1 0 +#define AHCI_BASE_2 0 +#define AHCI_BASE_3 0 +#define AHCI_BASE_4 0 + +#define AHCI_IRQ_0 0 +#define AHCI_IRQ_1 0 +#define AHCI_IRQ_2 0 +#define AHCI_IRQ_3 0 +#define AHCI_IRQ_4 0 + +/* UART */ +#if !defined(__ASSEMBLER__) +enum +{ + FUART0_ID = 0, + FUART1_ID, + FUART2_ID, + FUART3_ID, + + FUART_NUM +}; +#endif + +#define FUART0_IRQ_NUM 38 +#define FUART0_BASE_ADDR 0x28000000 +#define FUART0_CLK_FREQ_HZ 48000000 + +#define FUART1_IRQ_NUM 39 +#define FUART1_BASE_ADDR 0x28001000 +#define FUART1_CLK_FREQ_HZ 48000000 + +#define FUART2_IRQ_NUM 40 +#define FUART2_BASE_ADDR 0x28002000 +#define FUART2_CLK_FREQ_HZ 48000000 + +#define FUART3_IRQ_NUM 41 +#define FUART3_BASE_ADDR 0x28003000 +#define FUART3_CLK_FREQ_HZ 48000000 + +#define FT_STDOUT_BASE_ADDR FUART1_BASE_ADDR +#define FT_STDIN_BASE_ADDR FUART1_BASE_ADDR + +/* QSPI */ +#if !defined(__ASSEMBLER__) +enum +{ + FQSPI0_ID = 0, + + FQSPI_NUM +}; + +/* FQSPI cs 0_3, chip number */ +enum +{ + FQSPI_CS_0 = 0, + FQSPI_CS_1 = 1, + FQSPI_CS_2 = 2, + FQSPI_CS_3 = 3, + FQSPI_CS_NUM +}; +#endif + +#define FQSPI_BASE_ADDR 0x28014000 +#define FQSPI_MEM_START_ADDR 0x0 +#define FQSPI_MEM_END_ADDR 0x1FFFFFFF + +/* GIC v3 */ +#define ARM_GIC_NR_IRQS 1024 +#define ARM_GIC_IRQ_START 0 +#define FGIC_NUM 1 + + +#define GICV3_BASE_ADDR 0x29a00000U +#define GICV3_DISTRIBUTOR_BASE_ADDR (GICV3_BASE_ADDR + 0) +#define GICV3_RD_BASE_ADDR (GICV3_BASE_ADDR + 0x100000U) +#define GICV3_RD_OFFSET (2U << 16) +#define FT_GICV3_VECTORTABLE_NUM GIC_INT_MAX_NUM + +/* + * The maximum priority value that can be used in the GIC. + */ +#define GICV3_MAX_INTR_PRIO_VAL 240U +#define GICV3_INTR_PRIO_MASK 0x000000f0U + +#define ARM_GIC_IPI_COUNT 16 /* MPCore IPI count */ +#define SGI_INT_MAX 16 +#define SPI_START_INT_NUM 32 /* SPI start at ID32 */ +#define PPI_START_INT_NUM 16 /* PPI start at ID16 */ +#define GIC_INT_MAX_NUM 1020 /* GIC max interrupts count */ + +/* GPIO */ +#define FGPIO0_BASE_ADDR (0x28004000) +#define FGPIO1_BASE_ADDR (0x28005000) + +#define FGPIO0_ID 0 +#define FGPIO1_ID 1 +#define FGPIO_NUM 2 + +#define FGPIO0_IRQ_NUM (42) /* gpio0 irq number */ +#define FGPIO1_IRQ_NUM (43) /* gpio1 irq number */ + +/* IOMUX */ +#define FIOCTRL_REG_BASE_ADDR 0x28180000 + +/* SPI */ +#define FSPI0_BASE_ADDR 0x2800c000 +#define FSPI1_BASE_ADDR 0x28013000 +#define FSPI0_ID 0 +#define FSPI1_ID 1 +#define FSPI_CLK_FREQ_HZ 48000000 +#define FSPI_NUM 2 +#define FSPI0_IRQ_NUM 50 +#define FSPI1_IRQ_NUM 51 + +/* I2C */ +#if !defined(__ASSEMBLER__) +enum +{ + FI2C0_ID = 0, + FI2C1_ID = 1, + FI2C2_ID, + FI2C3_ID, + + FI2C_NUM +}; +#endif + +#define FI2C0_BASE_ADDR 0x28006000 +#define FI2C1_BASE_ADDR 0x28007000 +#define FI2C2_BASE_ADDR 0x28008000 +#define FI2C3_BASE_ADDR 0x28009000 + +#define FI2C0_IRQ_NUM 44 +#define FI2C1_IRQ_NUM 45 +#define FI2C2_IRQ_NUM 46 +#define FI2C3_IRQ_NUM 47 + +#define FI2C_CLK_FREQ_HZ 48000000 /* 48MHz */ + +/* WDT */ +#if !defined(__ASSEMBLER__) +enum +{ + FWDT0_ID = 0, + FWDT1_ID = 1, + + FWDT_NUM +}; +#endif + +#define FWDT0_REFRESH_BASE_ADDR 0x2800a000 +#define FWDT1_REFRESH_BASE_ADDR 0x28016000 + +#define FWDT_CONTROL_BASE_ADDR(x) ((x)+0x1000) + +#define FWDT0_IRQ_NUM 48 +#define FWDT1_IRQ_NUM 49 + +#define FWDT_CLK_FREQ_HZ 48000000 /* 48MHz */ + +/* SDCI */ +#if !defined(__ASSEMBLER__) +enum +{ + FSDMMC0_ID = 0, + + FSDMMC_NUM +}; +#endif + +#define FSDMMC0_BASE_ADDR 0x28207C00 + +#define FSDMMC0_DMA_IRQ_NUM 52 +#define FSDMMC0_CMD_IRQ_NUM 53 +#define FSDMMC0_ERR_IRQ_NUM 54 + +#define FSDMMC_CLK_FREQ_HZ 600000000 /* 600 MHz */ + +/* GMAC */ +#define FGMAC_PUB_REG_BASE_ADDR 0x2820B000 /* 公共寄存器基地址 */ + +#if !defined(__ASSEMBLER__) +enum +{ + FGMAC0_ID = 0, + FGMAC1_ID, + + FGMAC_NUM +}; +#endif + +#define FGMAC0_BASE_ADDR 0x2820C000 +#define FGMAC1_BASE_ADDR 0x28210000 + +#define FGMAC0_IRQ_NUM 81 +#define FGMAC1_IRQ_NUM 82 + +#define FGMAC_DMA_MIN_ALIGN 128 +#define FGMAC_MAX_PACKET_SIZE 1600 + +/* rtc base address */ +#define RTC_CONTROL_BASE 0x2800D000 + +#define FT_CPUS_NR CORE_NUM + + + +/* can */ +#define FCAN_CLK_FREQ_HZ 600000000 + +#define FCAN_REG_LENGTH 0x1000 +#define FCAN0_BASE_ADDR 0x28207000 +#define FCAN1_BASE_ADDR 0x28207400 +#define FCAN2_BASE_ADDR 0x28207800 +#define FCAN0_IRQ_NUM 119 +#define FCAN1_IRQ_NUM 123 +#define FCAN2_IRQNUM 124 + +#if !defined(__ASSEMBLER__) +enum +{ + FCAN0_ID = 0, + FCAN1_ID = 1, + FCAN2_ID = 2, + + FCAN_NUM +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // ! \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/e2000/d/fiopad_config.c b/bsp/phytium/libraries/standalone/board/e2000/d/fiopad_config.c index b1faaa7dad..2453c866e4 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/d/fiopad_config.c +++ b/bsp/phytium/libraries/standalone/board/e2000/d/fiopad_config.c @@ -14,7 +14,7 @@ * FilePath: fiopad_config.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for io-pad function definition + * Description:  This file is for io-pad function definition * * Modify History: * Ver   Who        Date         Changes @@ -70,33 +70,59 @@ void FIOPadSetSpimMux(u32 spim_id) */ void FIOPadSetGpioMux(u32 gpio_id, u32 pin_id) { - if (FGPIO_ID_3 == gpio_id) + if (FGPIO3_ID == gpio_id) { switch (pin_id) { - case 3: /* gpio 3-a-3 */ - FPinSetFunc(FIOPAD_A29, FPIN_FUNC6); - break; - case 4: /* gpio 3-a-4 */ - FPinSetFunc(FIOPAD_C29, FPIN_FUNC6); - break; - case 5: /* gpio 3-a-5 */ - FPinSetFunc(FIOPAD_C27, FPIN_FUNC6); - break; - case 6: /* gpio 3-a-6 */ - FPinSetFunc(FIOPAD_A27, FPIN_FUNC6); - break; - case 7: /* gpio 3-a-7 */ /*cannot use this pin*/ - FPinSetFunc(FIOPAD_AJ49, FPIN_FUNC6); - break; - case 8: /* gpio 3-a-8 */ - FPinSetFunc(FIOPAD_AL45, FPIN_FUNC6); - break; - case 9: /* gpio 3-a-9 */ - FPinSetFunc(FIOPAD_AL43, FPIN_FUNC6); - break; - default: - break; + case 3: /* gpio 3-a-3 */ + FPinSetFunc(FIOPAD_A29, FPIN_FUNC6); + break; + case 4: /* gpio 3-a-4 */ + FPinSetFunc(FIOPAD_C29, FPIN_FUNC6); + break; + case 5: /* gpio 3-a-5 */ + FPinSetFunc(FIOPAD_C27, FPIN_FUNC6); + break; + case 6: /* gpio 3-a-6 */ + FPinSetFunc(FIOPAD_A27, FPIN_FUNC6); + break; + case 7: /* gpio 3-a-7 */ /*cannot use this pin*/ + FPinSetFunc(FIOPAD_AJ49, FPIN_FUNC6); + break; + case 8: /* gpio 3-a-8 */ + FPinSetFunc(FIOPAD_AL45, FPIN_FUNC6); + break; + case 9: /* gpio 3-a-9 */ + FPinSetFunc(FIOPAD_AL43, FPIN_FUNC6); + break; + default: + break; + } + } + else if (FGPIO4_ID == gpio_id) + { + switch (pin_id) + { + case 5: /* gpio 4-a-5 */ + FPinSetFunc(FIOPAD_W47, FPIN_FUNC6); + break; + case 9: /* gpio 4-a-9 */ + FPinSetFunc(FIOPAD_U49, FPIN_FUNC6); + break; + case 10: /* gpio 4-a-10 */ + FPinSetFunc(FIOPAD_AE45, FPIN_FUNC6); + break; + case 11: /* gpio 4-a-11 */ + FPinSetFunc(FIOPAD_AC45, FPIN_FUNC6); + break; + case 12: /* gpio 4-a-12 */ + FPinSetFunc(FIOPAD_AE43, FPIN_FUNC6); + break; + case 13: /* gpio 4-a-13 */ + FPinSetFunc(FIOPAD_AA43, FPIN_FUNC6); + break; + default: + break; } } } @@ -109,15 +135,15 @@ void FIOPadSetGpioMux(u32 gpio_id, u32 pin_id) */ void FIOPadSetCanMux(u32 can_id) { - if (can_id == FCAN_INSTANCE_0) + if (can_id == FCAN0_ID) { - /* mio0 */ + /* can0 */ FPinSetFunc(FIOPAD_A37, FPIN_FUNC0); /* can0-tx: func 0 */ FPinSetFunc(FIOPAD_A39, FPIN_FUNC0); /* can0-rx: func 0 */ } - else if (can_id == FCAN_INSTANCE_1) + else if (can_id == FCAN1_ID) { - /* mio1 */ + /* can1 */ FPinSetFunc(FIOPAD_A41, FPIN_FUNC0); /* can1-tx: func 0 */ FPinSetFunc(FIOPAD_C41, FPIN_FUNC0); /* can1-rx: func 0 */ } @@ -137,7 +163,7 @@ void FIOPadSetCanMux(u32 can_id) void FIOPadSetQspiMux(u32 qspi_id, u32 cs_id) { - if (qspi_id == FQSPI_INSTANCE_0) + if (qspi_id == FQSPI0_ID) { /* add sck, io0-io3 iopad multiplex */ } @@ -174,102 +200,102 @@ void FIOPadSetQspiMux(u32 qspi_id, u32 cs_id) */ void FIOPadSetPwmMux(u32 pwm_id, u32 pwm_channel) { - FASSERT(pwm_id < FPWM_INSTANCE_NUM); + FASSERT(pwm_id < FPWM_NUM); FASSERT(pwm_channel < FPWM_CHANNEL_NUM); switch (pwm_id) { - case FPWM_INSTANCE_0: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_AL55, FPIN_FUNC1); /* PWM0_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_AJ53, FPIN_FUNC1); /* PWM1_OUT: func 1 */ - } - break; + case FPWM0_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_AL55, FPIN_FUNC1); /* PWM0_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_AJ53, FPIN_FUNC1); /* PWM1_OUT: func 1 */ + } + break; - case FPWM_INSTANCE_1: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_AG53, FPIN_FUNC1); /* PWM2_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_AC55, FPIN_FUNC1); /* PWM3_OUT: func 1 */ - } - break; + case FPWM1_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_AG53, FPIN_FUNC1); /* PWM2_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_AC55, FPIN_FUNC1); /* PWM3_OUT: func 1 */ + } + break; - case FPWM_INSTANCE_2: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_BA51, FPIN_FUNC1); /* PWM4_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C35, FPIN_FUNC2); /* PWM5_OUT: func 2 */ - } - break; + case FPWM2_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_BA51, FPIN_FUNC1); /* PWM4_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C35, FPIN_FUNC2); /* PWM5_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_3: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A33, FPIN_FUNC2); /* PWM6_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_A39, FPIN_FUNC2); /* PWM7_OUT: func 2 */ - } - break; + case FPWM3_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A33, FPIN_FUNC2); /* PWM6_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_A39, FPIN_FUNC2); /* PWM7_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_4: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_C41, FPIN_FUNC2); /* PWM8_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_A45, FPIN_FUNC2); /* PWM9_OUT: func 2 */ - } - break; + case FPWM4_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_C41, FPIN_FUNC2); /* PWM8_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_A45, FPIN_FUNC2); /* PWM9_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_5: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A47, FPIN_FUNC2); /* PWM10_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C29, FPIN_FUNC2); /* PWM11_OUT: func 2 */ - } - break; + case FPWM5_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A47, FPIN_FUNC2); /* PWM10_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C29, FPIN_FUNC2); /* PWM11_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_6: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A27, FPIN_FUNC2); /* PWM12_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_J35, FPIN_FUNC3); /* PWM13_OUT: func 3 */ - } - break; + case FPWM6_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A27, FPIN_FUNC2); /* PWM12_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_J35, FPIN_FUNC3); /* PWM13_OUT: func 3 */ + } + break; - case FPWM_INSTANCE_7: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_E39, FPIN_FUNC3); /* PWM14_OUT: func 3 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C39, FPIN_FUNC3); /* PWM15_OUT: func 3 */ - } - break; + case FPWM7_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_E39, FPIN_FUNC3); /* PWM14_OUT: func 3 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C39, FPIN_FUNC3); /* PWM15_OUT: func 3 */ + } + break; - default: - FIOPAD_ERROR("pwm id is error.\r\n"); - break; + default: + FIOPAD_ERROR("pwm id is error.\r\n"); + break; } } @@ -284,70 +310,37 @@ void FIOPadSetPwmMux(u32 pwm_id, u32 pwm_channel) void FIOPadSetAdcMux(u32 adc_id, u32 adc_channel) { - if (adc_id == FADC_INSTANCE_0) + if (adc_id == FADC0_ID) { switch (adc_channel) { - case FADC_CHANNEL_0: - FPinSetFunc(FIOPAD_R47, FPIN_FUNC7); /* adc0-0: func 7 */ - break; - case FADC_CHANNEL_1: - FPinSetFunc(FIOPAD_R45, FPIN_FUNC7); /* adc0-1: func 7 */ - break; - case FADC_CHANNEL_2: - FPinSetFunc(FIOPAD_N47, FPIN_FUNC7); /* adc0-2: func 7 */ - break; - case FADC_CHANNEL_3: - FPinSetFunc(FIOPAD_N51, FPIN_FUNC7); /* adc0-3: func 7 */ - break; - case FADC_CHANNEL_4: - FPinSetFunc(FIOPAD_L51, FPIN_FUNC7); /* adc0-4: func 7 */ - break; - case FADC_CHANNEL_5: - FPinSetFunc(FIOPAD_J51, FPIN_FUNC7); /* adc0-5: func 7 */ - break; - case FADC_CHANNEL_6: - FPinSetFunc(FIOPAD_J41, FPIN_FUNC7); /* adc0-6: func 7 */ - break; - case FADC_CHANNEL_7: - FPinSetFunc(FIOPAD_E43, FPIN_FUNC7); /* adc0-7: func 7 */ - break; - default: - FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); - break; - } - } - else if (adc_id == FADC_INSTANCE_1) - { - switch (adc_channel) - { - case FADC_CHANNEL_0: - FPinSetFunc(FIOPAD_G43, FPIN_FUNC7); /* adc1-0: func 7 */ - break; - case FADC_CHANNEL_1: - FPinSetFunc(FIOPAD_J43, FPIN_FUNC7); /* adc1-1: func 7 */ - break; - case FADC_CHANNEL_2: - FPinSetFunc(FIOPAD_J45, FPIN_FUNC7); /* adc1-2: func 7 */ - break; - case FADC_CHANNEL_3: - FPinSetFunc(FIOPAD_N45, FPIN_FUNC7); /* adc1-3: func 7 */ - break; - case FADC_CHANNEL_4: - FPinSetFunc(FIOPAD_L47, FPIN_FUNC7); /* adc1-4: func 7 */ - break; - case FADC_CHANNEL_5: - FPinSetFunc(FIOPAD_L45, FPIN_FUNC7); /* adc1-5: func 7 */ - break; - case FADC_CHANNEL_6: - FPinSetFunc(FIOPAD_N49, FPIN_FUNC7); /* adc1-6: func 7 */ - break; - case FADC_CHANNEL_7: - FPinSetFunc(FIOPAD_J49, FPIN_FUNC7); /* adc1-7: func 7 */ - break; - default: - FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); - break; + case FADC_CHANNEL_0: + FPinSetFunc(FIOPAD_R47, FPIN_FUNC7); /* adc0-0: func 7 */ + break; + case FADC_CHANNEL_1: + FPinSetFunc(FIOPAD_R45, FPIN_FUNC7); /* adc0-1: func 7 */ + break; + case FADC_CHANNEL_2: + FPinSetFunc(FIOPAD_N47, FPIN_FUNC7); /* adc0-2: func 7 */ + break; + case FADC_CHANNEL_3: + FPinSetFunc(FIOPAD_N51, FPIN_FUNC7); /* adc0-3: func 7 */ + break; + case FADC_CHANNEL_4: + FPinSetFunc(FIOPAD_L51, FPIN_FUNC7); /* adc0-4: func 7 */ + break; + case FADC_CHANNEL_5: + FPinSetFunc(FIOPAD_J51, FPIN_FUNC7); /* adc0-5: func 7 */ + break; + case FADC_CHANNEL_6: + FPinSetFunc(FIOPAD_J41, FPIN_FUNC7); /* adc0-6: func 7 */ + break; + case FADC_CHANNEL_7: + FPinSetFunc(FIOPAD_E43, FPIN_FUNC7); /* adc0-7: func 7 */ + break; + default: + FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); + break; } } else @@ -366,104 +359,104 @@ void FIOPadSetMioMux(u32 mio_id) { switch (mio_id) { - case MIO_INSTANCE_0: - { - FPinSetFunc(FIOPAD_A37, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A39, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_1: - { - FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_C41, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_2: - { - FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_3: - { - FPinSetFunc(FIOPAD_BA51, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_BA49, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_4: - { - FPinSetFunc(FIOPAD_R55, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U55, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_5: - { - FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U53, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_6: - { - FPinSetFunc(FIOPAD_AA53, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_AA55, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_7: - { - FPinSetFunc(FIOPAD_A35, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_C35, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_8: - { - FPinSetFunc(FIOPAD_AA45, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_9: - { - FPinSetFunc(FIOPAD_AA47, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U45, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_10: - { - FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_11: - { - FPinSetFunc(FIOPAD_N23, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L25, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_12: - { - FPinSetFunc(FIOPAD_E37, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L41, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_13: - { - FPinSetFunc(FIOPAD_J45, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_N45, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_14: - { - FPinSetFunc(FIOPAD_L47, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_L45, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_15: - { - FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* sda */ - } - break; - default: + case FMIO0_ID: + { + FPinSetFunc(FIOPAD_A37, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A39, FPIN_FUNC5); /* sda */ + } break; + case FMIO1_ID: + { + FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_C41, FPIN_FUNC5); /* sda */ + } + break; + case FMIO2_ID: + { + FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* sda */ + } + break; + case FMIO3_ID: + { + FPinSetFunc(FIOPAD_BA51, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_BA49, FPIN_FUNC4); /* sda */ + } + break; + case FMIO4_ID: + { + FPinSetFunc(FIOPAD_R55, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U55, FPIN_FUNC4); /* sda */ + } + break; + case FMIO5_ID: + { + FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U53, FPIN_FUNC4); /* sda */ + } + break; + case FMIO6_ID: + { + FPinSetFunc(FIOPAD_AA53, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_AA55, FPIN_FUNC4); /* sda */ + } + break; + case FMIO7_ID: + { + FPinSetFunc(FIOPAD_A35, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_C35, FPIN_FUNC4); /* sda */ + } + break; + case FMIO8_ID: + { + FPinSetFunc(FIOPAD_AA45, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* sda */ + } + break; + case FMIO9_ID: + { + FPinSetFunc(FIOPAD_AA47, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U45, FPIN_FUNC4); /* sda */ + } + break; + case FMIO10_ID: + { + FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* sda */ + } + break; + case FMIO11_ID: + { + FPinSetFunc(FIOPAD_N23, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L25, FPIN_FUNC3); /* sda */ + } + break; + case FMIO12_ID: + { + FPinSetFunc(FIOPAD_E37, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L41, FPIN_FUNC3); /* sda */ + } + break; + case FMIO13_ID: + { + FPinSetFunc(FIOPAD_J45, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_N45, FPIN_FUNC6); /* sda */ + } + break; + case FMIO14_ID: + { + FPinSetFunc(FIOPAD_L47, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_L45, FPIN_FUNC6); /* sda */ + } + break; + case FMIO15_ID: + { + FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* sda */ + } + break; + default: + break; } } @@ -477,56 +470,56 @@ void FIOPadSetTachoMux(u32 pwm_in_id) { switch (pwm_in_id) { - case TACHO_INSTANCE_0: - FPinSetFunc(FIOPAD_AN53, FPIN_FUNC1); - break; - case TACHO_INSTANCE_1: - FPinSetFunc(FIOPAD_AJ55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_2: - FPinSetFunc(FIOPAD_AG55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_3: - FPinSetFunc(FIOPAD_AE55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_4: - FPinSetFunc(FIOPAD_AC53, FPIN_FUNC1); - break; - case TACHO_INSTANCE_5: - FPinSetFunc(FIOPAD_BA49, FPIN_FUNC1); - break; - case TACHO_INSTANCE_6: - FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); - break; - case TACHO_INSTANCE_7: - FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); - break; - case TACHO_INSTANCE_8: - FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); - break; - case TACHO_INSTANCE_9: - FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); - break; - case TACHO_INSTANCE_10: - FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); - break; - case TACHO_INSTANCE_11: - FPinSetFunc(FIOPAD_A29, FPIN_FUNC2); - break; - case TACHO_INSTANCE_12: - FPinSetFunc(FIOPAD_C27, FPIN_FUNC2); - break; - case TACHO_INSTANCE_13: - FPinSetFunc(FIOPAD_AA45, FPIN_FUNC2); - break; - case TACHO_INSTANCE_14: - FPinSetFunc(FIOPAD_AA47, FPIN_FUNC2); - break; - case TACHO_INSTANCE_15: - FPinSetFunc(FIOPAD_G55, FPIN_FUNC2); - break; - default: - break; + case FTACHO0_ID: + FPinSetFunc(FIOPAD_AN53, FPIN_FUNC1); + break; + case FTACHO1_ID: + FPinSetFunc(FIOPAD_AJ55, FPIN_FUNC1); + break; + case FTACHO2_ID: + FPinSetFunc(FIOPAD_AG55, FPIN_FUNC1); + break; + case FTACHO3_ID: + FPinSetFunc(FIOPAD_AE55, FPIN_FUNC1); + break; + case FTACHO4_ID: + FPinSetFunc(FIOPAD_AC53, FPIN_FUNC1); + break; + case FTACHO5_ID: + FPinSetFunc(FIOPAD_BA49, FPIN_FUNC1); + break; + case FTACHO6_ID: + FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); + break; + case FTACHO7_ID: + FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); + break; + case FTACHO8_ID: + FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); + break; + case FTACHO9_ID: + FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); + break; + case FTACHO10_ID: + FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); + break; + case FTACHO11_ID: + FPinSetFunc(FIOPAD_A29, FPIN_FUNC2); + break; + case FTACHO12_ID: + FPinSetFunc(FIOPAD_C27, FPIN_FUNC2); + break; + case FTACHO13_ID: + FPinSetFunc(FIOPAD_AA45, FPIN_FUNC2); + break; + case FTACHO14_ID: + FPinSetFunc(FIOPAD_AA47, FPIN_FUNC2); + break; + case FTACHO15_ID: + FPinSetFunc(FIOPAD_G55, FPIN_FUNC2); + break; + default: + break; } } @@ -540,23 +533,23 @@ void FIOPadSetUartMux(u32 uart_id) { switch (uart_id) { - case FUART0_ID: - FPinSetFunc(FIOPAD_J33, FPIN_FUNC4); - FPinSetFunc(FIOPAD_J35, FPIN_FUNC4); - break; - case FUART1_ID: - FPinSetFunc(FIOPAD_AW47, FPIN_FUNC0); - FPinSetFunc(FIOPAD_AU47, FPIN_FUNC0); - break; - case FUART2_ID: - FPinSetFunc(FIOPAD_A43, FPIN_FUNC0); - FPinSetFunc(FIOPAD_A45, FPIN_FUNC0); - break; - case FUART3_ID: - FPinSetFunc(FIOPAD_L33, FPIN_FUNC2); - FPinSetFunc(FIOPAD_N31, FPIN_FUNC2); - break; - default: - break; + case FUART0_ID: + FPinSetFunc(FIOPAD_J33, FPIN_FUNC4); + FPinSetFunc(FIOPAD_J35, FPIN_FUNC4); + break; + case FUART1_ID: + FPinSetFunc(FIOPAD_AW47, FPIN_FUNC0); + FPinSetFunc(FIOPAD_AU47, FPIN_FUNC0); + break; + case FUART2_ID: + FPinSetFunc(FIOPAD_A43, FPIN_FUNC0); + FPinSetFunc(FIOPAD_A45, FPIN_FUNC0); + break; + case FUART3_ID: + FPinSetFunc(FIOPAD_L33, FPIN_FUNC2); + FPinSetFunc(FIOPAD_N31, FPIN_FUNC2); + break; + default: + break; } } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/e2000/d/fparameters.h b/bsp/phytium/libraries/standalone/board/e2000/d/fparameters.h index 3703d3e78b..7857ed48ce 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/d/fparameters.h +++ b/bsp/phytium/libraries/standalone/board/e2000/d/fparameters.h @@ -14,7 +14,7 @@ * FilePath: fparameters.h * Date: 2022-02-11 13:33:28 * LastEditTime: 2022-02-17 18:00:50 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.c b/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.c index e26cafcc8d..3be376cce1 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.c +++ b/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.c @@ -14,7 +14,7 @@ * FilePath: fiopad_comm.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for io-pad function definition + * Description:  This file is for io-pad function definition * * Modify History: * Ver   Who        Date         Changes @@ -202,7 +202,7 @@ void FPinGetConfig(const FPinIndex pin, FPinFunc *func, FPinPull *pull, FPinDriv if (drive) { - *pull = FIOPAD_X_REG0_DRIVE_GET(reg_val); + *drive = FIOPAD_X_REG0_DRIVE_GET(reg_val); } return; @@ -331,16 +331,24 @@ boolean FPinGetDelayEn(const FPinIndex pin, FPinDelayDir dir) if (FPIN_OUTPUT_DELAY == dir) { if (FIOPAD_X_REG1_OUT_DELAY_EN & reg_val) + { enabled = TRUE; + } else + { enabled = FALSE; + } } else if (FPIN_INPUT_DELAY == dir) { if (FIOPAD_X_REG1_IN_DELAY_EN & reg_val) + { enabled = TRUE; + } else + { enabled = FALSE; + } } else { @@ -424,16 +432,24 @@ void FPinSetDelayEn(const FPinIndex pin, FPinDelayDir dir, boolean enable) if (FPIN_OUTPUT_DELAY == dir) { if (enable) + { reg_val |= FIOPAD_X_REG1_OUT_DELAY_EN; + } else + { reg_val &= ~FIOPAD_X_REG1_OUT_DELAY_EN; + } } else if (FPIN_INPUT_DELAY == dir) { if (enable) + { reg_val |= FIOPAD_X_REG1_IN_DELAY_EN; + } else + { reg_val &= ~FIOPAD_X_REG1_IN_DELAY_EN; + } } else { diff --git a/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.h b/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.h index 311fb6f076..8251caee75 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.h +++ b/bsp/phytium/libraries/standalone/board/e2000/fiopad_comm.h @@ -17,10 +17,10 @@ extern "C" /***************** Macros (Inline Functions) Definitions *********************/ #define FIOPAD_INDEX(offset) \ - { \ + { \ /* reg_off */ (offset), \ /* reg_bit */ (0) \ - } + } /*****************************************************************************/ /* register offset of iopad function / pull / driver strength */ diff --git a/bsp/phytium/libraries/standalone/board/e2000/fparameters_comm.h b/bsp/phytium/libraries/standalone/board/e2000/fparameters_comm.h index 5f807e7843..7707654654 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/fparameters_comm.h +++ b/bsp/phytium/libraries/standalone/board/e2000/fparameters_comm.h @@ -14,7 +14,7 @@ * FilePath: fparameters_comm.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-17 18:01:11 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes @@ -44,55 +44,55 @@ extern "C" #define FT_DEV_END_ADDR 0x2FFFFFFFU /* PCI */ -#define FT_PCIE_NUM 1 -#define FT_PCIE0_ID 0 -#define FT_PCIE0_MISC_IRQ_NUM 40 +#define FPCIE_NUM 1 +#define FPCIE0_ID 0 +#define FPCIE0_MISC_IRQ_NUM 40 -#define FT_PCIE_CFG_MAX_NUM_OF_BUS 256 -#define FT_PCIE_CFG_MAX_NUM_OF_DEV 32 -#define FT_PCIE_CFG_MAX_NUM_OF_FUN 8 +#define FPCIE_CFG_MAX_NUM_OF_BUS 256 +#define FPCIE_CFG_MAX_NUM_OF_DEV 32 +#define FPCIE_CFG_MAX_NUM_OF_FUN 8 -#define FT_PCI_CONFIG_BASEADDR 0x40000000U -#define FT_PCI_CONFIG_REG_LENGTH 0x10000000U +#define FPCI_CONFIG_BASE_ADDR 0x40000000U +#define FPCI_CONFIG_REG_LENGTH 0x10000000U -#define FT_PCI_IO_CONFIG_BASEADDR 0x50000000U -#define FT_PCI_IO_CONFIG_REG_LENGTH 0x08000000U +#define FPCI_IO_CONFIG_BASE_ADDR 0x50000000U +#define FPCI_IO_CONFIG_REG_LENGTH 0x08000000U -#define FT_PCI_MEM32_BASEADDR 0x58000000U -#define FT_PCI_MEM32_REG_LENGTH 0x27FFFFFFU +#define FPCI_MEM32_BASE_ADDR 0x58000000U +#define FPCI_MEM32_REG_LENGTH 0x27FFFFFFU -#define FT_PCI_MEM64_BASEADDR 0x1000000000U -#define FT_PCI_MEM64_REG_LENGTH 0x1000000000U +#define FPCI_MEM64_BASE_ADDR 0x1000000000U +#define FPCI_MEM64_REG_LENGTH 0x1000000000U -#define FT_PCI_EU0_C0_CONTROL_BASEADDR 0x29000000U -#define FT_PCI_EU0_C1_CONTROL_BASEADDR 0x29010000U -#define FT_PCI_EU0_C2_CONTROL_BASEADDR 0x29020000U -#define FT_PCI_EU1_C0_CONTROL_BASEADDR 0x29030000U -#define FT_PCI_EU1_C1_CONTROL_BASEADDR 0x29040000U -#define FT_PCI_EU1_C2_CONTROL_BASEADDR 0x29050000U +#define FPCI_EU0_C0_CONTROL_BASE_ADDR 0x29000000U +#define FPCI_EU0_C1_CONTROL_BASE_ADDR 0x29010000U +#define FPCI_EU0_C2_CONTROL_BASE_ADDR 0x29020000U +#define FPCI_EU1_C0_CONTROL_BASE_ADDR 0x29030000U +#define FPCI_EU1_C1_CONTROL_BASE_ADDR 0x29040000U +#define FPCI_EU1_C2_CONTROL_BASE_ADDR 0x29050000U -#define FT_PCI_EU0_CONFIG_BASEADDR 0x29100000U -#define FT_PCI_EU1_CONFIG_BASEADDR 0x29101000U +#define FPCI_EU0_CONFIG_BASE_ADDR 0x29100000U +#define FPCI_EU1_CONFIG_BASE_ADDR 0x29101000U -#define FT_PCI_INTA_IRQ_NUM 36 -#define FT_PCI_INTB_IRQ_NUM 37 -#define FT_PCI_INTC_IRQ_NUM 38 -#define FT_PCI_INTD_IRQ_NUM 39 +#define FPCI_INTA_IRQ_NUM 36 +#define FPCI_INTB_IRQ_NUM 37 +#define FPCI_INTC_IRQ_NUM 38 +#define FPCI_INTD_IRQ_NUM 39 -#define FT_PCI_NEED_SKIP 0 +#define FPCI_NEED_SKIP 0 -#define FT_PCI_INTX_PEU0_STAT 0x29100000U -#define FT_PCI_INTX_PEU1_STAT 0x29101000U +#define FPCI_INTX_PEU0_STAT 0x29100000U +#define FPCI_INTX_PEU1_STAT 0x29101000U -#define FT_PCI_INTX_EU0_C0_CONTROL 0x29000184U -#define FT_PCI_INTX_EU0_C1_CONTROL 0x29010184U -#define FT_PCI_INTX_EU0_C2_CONTROL 0x29020184U -#define FT_PCI_INTX_EU1_C0_CONTROL 0x29030184U -#define FT_PCI_INTX_EU1_C1_CONTROL 0x29040184U -#define FT_PCI_INTX_EU1_C2_CONTROL 0x29050184U +#define FPCI_INTX_EU0_C0_CONTROL 0x29000184U +#define FPCI_INTX_EU0_C1_CONTROL 0x29010184U +#define FPCI_INTX_EU0_C2_CONTROL 0x29020184U +#define FPCI_INTX_EU1_C0_CONTROL 0x29030184U +#define FPCI_INTX_EU1_C1_CONTROL 0x29040184U +#define FPCI_INTX_EU1_C2_CONTROL 0x29050184U -#define FT_PCI_INTX_CONTROL_NUM 6 /* Total number of controllers */ -#define FT_PCI_INTX_SATA_NUM 2 /* Total number of controllers */ +#define FPCI_INTX_CONTROL_NUM 6 /* Total number of controllers */ +#define FPCI_INTX_SATA_NUM 2 /* Total number of controllers */ /* platform ahci host */ @@ -110,22 +110,37 @@ extern "C" #define AHCI_IRQ_4 0 /* sata controller */ -#define FSATA0_BASEADDR 0x31A40000U -#define FSATA1_BASEADDR 0x32014000U +#define FSATA0_BASE_ADDR 0x31A40000U +#define FSATA1_BASE_ADDR 0x32014000U -#define FSATA0_IRQNUM 74 -#define FSATA1_IRQNUM 75 +#define FSATA0_IRQ_NUM 74 +#define FSATA1_IRQ_NUM 75 #if !defined(__ASSEMBLER__) -typedef enum +enum { - FSATA_INSTANCE_0 = 0, - FSATA_INSTANCE_1 = 1, + FSATA0_ID = 0, + FSATA1_ID = 1, - FSATA_INSTANCE_NUM -} FSataInstance; + FSATA_NUM +}; #endif +/* SCMI and MHU */ +#define FSCMI_MHU_BASE_ADDR 0x32a00000 +#define FSCMI_MHU_IRQ_NUM (22U + 32U) +#define FSCMI_SHR_MEM_ADDR 0x32a11400 +#define FSCMI_MEM_TX_OFSET 0x1400 +#define FSCMI_MEM_RX_OFSET 0x1000 +#define FSCMI_SHR_MEM_SIZE 0x400 + +#define FSCMI_MSG_SIZE 128 +#define FSCMI_MAX_STR_SIZE 16 +#define FSCMI_MAX_NUM_SENSOR 16 +#define FSCMI_MAX_PROTOCOLS_IMP 16 +#define FSCMI_MAX_PERF_DOMAINS 3 +#define FSCMI_MAX_OPPS 4 + /* Generic Timer */ #define GENERIC_TIMER_CLK_FREQ_MHZ 48U #define GENERIC_TIMER_NS_IRQ_NUM 30U @@ -169,7 +184,7 @@ typedef enum #define GICV3_MAX_INTR_PRIO_VAL 240U #define GICV3_INTR_PRIO_MASK 0x000000f0U -#define ARM_GIC_NR_IRQS 160U +#define ARM_GIC_NR_IRQS 270U #define ARM_GIC_IRQ_START 0U #define FGIC_NUM 1U @@ -179,28 +194,35 @@ typedef enum #define PPI_START_INT_NUM 16U /* PPI start at ID16 */ #define GIC_INT_MAX_NUM 1020U /* GIC max interrupts count */ -#define GICV3_BASEADDRESS 0x30800000U -#define GICV3_DISTRIBUTOR_BASEADDRESS (GICV3_BASEADDRESS + 0) -#define GICV3_RD_BASEADDRESS (GICV3_BASEADDRESS + 0x80000U) +#define GICV3_BASE_ADDR 0x30800000U +#define GICV3_DISTRIBUTOR_BASE_ADDR (GICV3_BASE_ADDR + 0) +#define GICV3_RD_BASE_ADDR (GICV3_BASE_ADDR + 0x80000U) #define GICV3_RD_OFFSET (2U << 16) #define FT_GICV3_VECTORTABLE_NUM GIC_INT_MAX_NUM /* GPIO */ -#define FGPIO_ID_0 0U -#define FGPIO_ID_1 1U -#define FGPIO_ID_2 2U -#define FGPIO_WITH_PIN_IRQ 2U /* max id of gpio assign irq for each pin */ -#define FGPIO_ID_3 3U -#define FGPIO_ID_4 4U -#define FGPIO_ID_5 5U -#define FGPIO_NUM 6U +#if !defined(__ASSEMBLER__) +enum +{ + FGPIO0_ID = 0, + FGPIO1_ID = 1, + FGPIO2_ID, + FGPIO3_ID, + FGPIO4_ID, + FGPIO5_ID, -#define FGPIO_0_BASE_ADDR 0x28034000U -#define FGPIO_1_BASE_ADDR 0x28035000U -#define FGPIO_2_BASE_ADDR 0x28036000U -#define FGPIO_3_BASE_ADDR 0x28037000U -#define FGPIO_4_BASE_ADDR 0x28038000U -#define FGPIO_5_BASE_ADDR 0x28039000U + FGPIO_NUM +}; +#endif + +#define FGPIO_WITH_PIN_IRQ 2U /* max id of gpio assign irq for each pin */ + +#define FGPIO0_BASE_ADDR 0x28034000U +#define FGPIO1_BASE_ADDR 0x28035000U +#define FGPIO2_BASE_ADDR 0x28036000U +#define FGPIO3_BASE_ADDR 0x28037000U +#define FGPIO4_BASE_ADDR 0x28038000U +#define FGPIO5_BASE_ADDR 0x28039000U #define FGPIO_CTRL_PIN_NUM 16U @@ -214,8 +236,8 @@ typedef enum #define FGPIO_PIN_IRQ_TOTAL 51U /* SPI */ -#define FSPI0_BASE 0x2803A000U -#define FSPI1_BASE 0x2803B000U +#define FSPI0_BASE_ADDR 0x2803A000U +#define FSPI1_BASE_ADDR 0x2803B000U #define FSPI2_BASE 0x2803C000U #define FSPI3_BASE 0x2803D000U #define FSPI0_ID 0U @@ -228,90 +250,88 @@ typedef enum #define FSPI2_IRQ_NUM 193U #define FSPI3_IRQ_NUM 194U -#define FSPI_FREQ 50000000U -#define FSPI_DEVICE_NUM 4U +#define FSPI_CLK_FREQ_HZ 50000000U +#define FSPI_NUM 4U /* XMAC */ -#define FT_XMAC_NUM 4U +#define FXMAC_NUM 4U -#define FT_XMAC0_ID 0U -#define FT_XMAC1_ID 1U -#define FT_XMAC2_ID 2U -#define FT_XMAC3_ID 3U +#define FXMAC0_ID 0U +#define FXMAC1_ID 1U +#define FXMAC2_ID 2U +#define FXMAC3_ID 3U -#define FT_XMAC0_BASEADDRESS 0x3200C000U -#define FT_XMAC1_BASEADDRESS 0x3200E000U -#define FT_XMAC2_BASEADDRESS 0x32010000U -#define FT_XMAC3_BASEADDRESS 0x32012000U +#define FXMAC0_BASE_ADDR 0x3200C000U +#define FXMAC1_BASE_ADDR 0x3200E000U +#define FXMAC2_BASE_ADDR 0x32010000U +#define FXMAC3_BASE_ADDR 0x32012000U -#define FT_XMAC0_MODE_SEL_BASEADDRESS 0x3200DC00U -#define FT_XMAC0_LOOPBACK_SEL_BASEADDRESS 0x3200DC04U -#define FT_XMAC1_MODE_SEL_BASEADDRESS 0x3200FC00U -#define FT_XMAC1_LOOPBACK_SEL_BASEADDRESS 0x3200FC04U -#define FT_XMAC2_MODE_SEL_BASEADDRESS 0x32011C00U -#define FT_XMAC2_LOOPBACK_SEL_BASEADDRESS 0x32011C04U -#define FT_XMAC3_MODE_SEL_BASEADDRESS 0x32013C00U -#define FT_XMAC3_LOOPBACK_SEL_BASEADDRESS 0x32013C04U +#define FXMAC0_MODE_SEL_BASE_ADDR 0x3200DC00U +#define FXMAC0_LOOPBACK_SEL_BASE_ADDR 0x3200DC04U +#define FXMAC1_MODE_SEL_BASE_ADDR 0x3200FC00U +#define FXMAC1_LOOPBACK_SEL_BASE_ADDR 0x3200FC04U +#define FXMAC2_MODE_SEL_BASE_ADDR 0x32011C00U +#define FXMAC2_LOOPBACK_SEL_BASE_ADDR 0x32011C04U +#define FXMAC3_MODE_SEL_BASE_ADDR 0x32013C00U +#define FXMAC3_LOOPBACK_SEL_BASE_ADDR 0x32013C04U -#define FT_XMAC0_PCLK 50000000U -#define FT_XMAC1_PCLK 50000000U -#define FT_XMAC2_PCLK 50000000U -#define FT_XMAC3_PCLK 50000000U -#define FT_XMAC0_HOTPLUG_IRQ_NUM (53U + 30U) -#define FT_XMAC1_HOTPLUG_IRQ_NUM (54U + 30U) -#define FT_XMAC2_HOTPLUG_IRQ_NUM (55U + 30U) -#define FT_XMAC3_HOTPLUG_IRQ_NUM (56U + 30U) +#define FXMAC0_PCLK 50000000U +#define FXMAC1_PCLK 50000000U +#define FXMAC2_PCLK 50000000U +#define FXMAC3_PCLK 50000000U +#define FXMAC0_HOTPLUG_IRQ_NUM (53U + 30U) +#define FXMAC1_HOTPLUG_IRQ_NUM (54U + 30U) +#define FXMAC2_HOTPLUG_IRQ_NUM (55U + 30U) +#define FXMAC3_HOTPLUG_IRQ_NUM (56U + 30U) -#define FT_XMAC_QUEUE_MAX_NUM 16U +#define FXMAC_QUEUE_MAX_NUM 16U -#define FT_XMAC0_QUEUE0_IRQ_NUM (57U + 30U) -#define FT_XMAC0_QUEUE1_IRQ_NUM (58U + 30U) -#define FT_XMAC0_QUEUE2_IRQ_NUM (59U + 30U) -#define FT_XMAC0_QUEUE3_IRQ_NUM (60U + 30U) -#define FT_XMAC0_QUEUE4_IRQ_NUM (30U + 30U) -#define FT_XMAC0_QUEUE5_IRQ_NUM (31U + 30U) -#define FT_XMAC0_QUEUE6_IRQ_NUM (32U + 30U) -#define FT_XMAC0_QUEUE7_IRQ_NUM (33U + 30U) +#define FXMAC0_QUEUE0_IRQ_NUM (57U + 30U) +#define FXMAC0_QUEUE1_IRQ_NUM (58U + 30U) +#define FXMAC0_QUEUE2_IRQ_NUM (59U + 30U) +#define FXMAC0_QUEUE3_IRQ_NUM (60U + 30U) +#define FXMAC0_QUEUE4_IRQ_NUM (30U + 30U) +#define FXMAC0_QUEUE5_IRQ_NUM (31U + 30U) +#define FXMAC0_QUEUE6_IRQ_NUM (32U + 30U) +#define FXMAC0_QUEUE7_IRQ_NUM (33U + 30U) -#define FT_XMAC1_QUEUE0_IRQ_NUM (61U + 30U) -#define FT_XMAC1_QUEUE1_IRQ_NUM (62U + 30U) -#define FT_XMAC1_QUEUE2_IRQ_NUM (63U + 30U) -#define FT_XMAC1_QUEUE3_IRQ_NUM (64U + 30U) +#define FXMAC1_QUEUE0_IRQ_NUM (61U + 30U) +#define FXMAC1_QUEUE1_IRQ_NUM (62U + 30U) +#define FXMAC1_QUEUE2_IRQ_NUM (63U + 30U) +#define FXMAC1_QUEUE3_IRQ_NUM (64U + 30U) -#define FT_XMAC2_QUEUE0_IRQ_NUM (66U + 30U) -#define FT_XMAC2_QUEUE1_IRQ_NUM (67U + 30U) -#define FT_XMAC2_QUEUE2_IRQ_NUM (68U + 30U) -#define FT_XMAC2_QUEUE3_IRQ_NUM (69U + 30U) +#define FXMAC2_QUEUE0_IRQ_NUM (66U + 30U) +#define FXMAC2_QUEUE1_IRQ_NUM (67U + 30U) +#define FXMAC2_QUEUE2_IRQ_NUM (68U + 30U) +#define FXMAC2_QUEUE3_IRQ_NUM (69U + 30U) -#define FT_XMAC3_QUEUE0_IRQ_NUM (70U + 30U) -#define FT_XMAC3_QUEUE1_IRQ_NUM (71U + 30U) -#define FT_XMAC3_QUEUE2_IRQ_NUM (72U + 30U) -#define FT_XMAC3_QUEUE3_IRQ_NUM (73U + 30U) +#define FXMAC3_QUEUE0_IRQ_NUM (70U + 30U) +#define FXMAC3_QUEUE1_IRQ_NUM (71U + 30U) +#define FXMAC3_QUEUE2_IRQ_NUM (72U + 30U) +#define FXMAC3_QUEUE3_IRQ_NUM (73U + 30U) -#define FT_XMAC_PHY_MAX_NUM 32U +#define FXMAC_PHY_MAX_NUM 32U /* QSPI */ - -#define FQSPI_BASEADDR 0x028008000U - #if !defined(__ASSEMBLER__) - -typedef enum +enum { - FQSPI_INSTANCE_0 = 0, + FQSPI0_ID = 0, - FQSPI_INSTANCE_NUM -} FQspiInstance; + FQSPI_NUM +}; + +#define FQSPI_BASE_ADDR 0x028008000U /* FQSPI cs 0_3, chip number */ -typedef enum +enum { FQSPI_CS_0 = 0, FQSPI_CS_1 = 1, FQSPI_CS_2 = 2, FQSPI_CS_3 = 3, FQSPI_CS_NUM -} FQspiChipCS; +}; #endif @@ -321,113 +341,112 @@ typedef enum #define FQSPI_MEM_END_ADDR_64 0x17FFFFFFFU /* 2GB */ /* TIMER and TACHO */ -#define TIMER_NUM 38U -#define TACHO_NUM 16U -#define TIMER_CLK_FREQ_HZ 50000000U /* 50MHz */ -#define TIMER_TICK_PERIOD_NS 20U /* 20ns */ -#define TIMER_TACHO_IRQ_ID(n) (226U + (n)) -#define TIMER_TACHO_BASE_ADDR(n) (0x28054000U + 0x1000U * (n)) +#define FTIMER_NUM 38U +#define FTIMER_CLK_FREQ_HZ 50000000U /* 50MHz */ +#define FTIMER_TICK_PERIOD_NS 20U /* 20ns */ +#define FTIMER_TACHO_IRQ_NUM(n) (226U + (n)) +#define FTIMER_TACHO_BASE_ADDR(n) (0x28054000U + 0x1000U * (n)) #if !defined(__ASSEMBLER__) -typedef enum +enum { - TACHO_INSTANCE_0 = 0, - TACHO_INSTANCE_1 = 1, - TACHO_INSTANCE_2 = 2, - TACHO_INSTANCE_3 = 3, - TACHO_INSTANCE_4 = 4, - TACHO_INSTANCE_5 = 5, - TACHO_INSTANCE_6 = 6, - TACHO_INSTANCE_7 = 7, - TACHO_INSTANCE_8 = 8, - TACHO_INSTANCE_9 = 9, - TACHO_INSTANCE_10 = 10, - TACHO_INSTANCE_11 = 11, - TACHO_INSTANCE_12 = 12, - TACHO_INSTANCE_13 = 13, - TACHO_INSTANCE_14 = 14, - TACHO_INSTANCE_15 = 15, + FTACHO0_ID = 0, + FTACHO1_ID = 1, + FTACHO2_ID, + FTACHO3_ID, + FTACHO4_ID, + FTACHO5_ID, + FTACHO6_ID, + FTACHO7_ID, + FTACHO8_ID, + FTACHO9_ID, + FTACHO10_ID, + FTACHO11_ID, + FTACHO12_ID, + FTACHO13_ID, + FTACHO14_ID, + FTACHO15_ID, - TACHO_INSTANCE_NUM -} TachoInstance; + FTACHO_NUM +} ; #endif /* GDMA */ #define FGDMA0_ID 0U #define FGDMA0_BASE_ADDR 0x32B34000U -#define FGDMA0_IRQ_NUM 266U - +#define FGDMA0_CHANNEL0_IRQ_NUM 266U +#define FGDMA_NUM_OF_CHAN 16 #define FGDMA_INSTANCE_NUM 1U +#define FGDMA0_CAPACITY (1U<<0) /* CANFD */ -#define FCAN_REF_CLOCK 200000000U +#define FCAN_CLK_FREQ_HZ 200000000U -#define FCAN0_BASEADDR 0x2800A000U -#define FCAN1_BASEADDR 0x2800B000U +#define FCAN0_BASE_ADDR 0x2800A000U +#define FCAN1_BASE_ADDR 0x2800B000U -#define FCAN0_IRQNUM 113U -#define FCAN1_IRQNUM 114U +#define FCAN0_IRQ_NUM 113U +#define FCAN1_IRQ_NUM 114U #if !defined(__ASSEMBLER__) -typedef enum +enum { - FCAN_INSTANCE_0 = 0, - FCAN_INSTANCE_1 = 1, + FCAN0_ID = 0, + FCAN1_ID = 1, - FCAN_INSTANCE_NUM -} FCanInstance; + FCAN_NUM +}; #endif /* WDT */ #if !defined(__ASSEMBLER__) -typedef enum +enum { - FWDT_INSTANCE_0 = 0, - FWDT_INSTANCE_1, + FWDT0_ID = 0, + FWDT1_ID, - FWDT_INSTANCE_NUM -} FWdtInstance; + FWDT_NUM +}; #endif -#define FWDT0_REFRESH_BASE 0x28040000U -#define FWDT0_CONTROL_BASE 0x28041000U -#define FWDT1_REFRESH_BASE 0x28042000U -#define FWDT1_CONTROL_BASE 0x28043000U +#define FWDT0_REFRESH_BASE_ADDR 0x28040000U +#define FWDT1_REFRESH_BASE_ADDR 0x28042000U -#define FWDT0_INTR_IRQ 196U -#define FWDT1_INTR_IRQ 197U +#define FWDT_CONTROL_BASE_ADDR(x) ((x)+0x1000) -#define FWDT_CLK 48000000U /* 48MHz */ +#define FWDT0_IRQ_NUM 196U +#define FWDT1_IRQ_NUM 197U + +#define FWDT_CLK_FREQ_HZ 48000000U /* 48MHz */ /*MIO*/ -#define FMIO_NUM 16 #define FMIO_BASE_ADDR(n) (0x28014000 + 0x2000 * (n)) #define FMIO_CONF_ADDR(n) FMIO_BASE_ADDR(n)+0x1000 #define FMIO_IRQ_NUM(n) (124+n) -#define MIO_REF_CLK_HZ 50000000 /* 50MHz */ +#define FMIO_CLK_FREQ_HZ 50000000 /* 50MHz */ #if !defined(__ASSEMBLER__) -typedef enum +enum { - MIO_INSTANCE_0 = 0, - MIO_INSTANCE_1, - MIO_INSTANCE_2, - MIO_INSTANCE_3, - MIO_INSTANCE_4, - MIO_INSTANCE_5, - MIO_INSTANCE_6, - MIO_INSTANCE_7, - MIO_INSTANCE_8, - MIO_INSTANCE_9, - MIO_INSTANCE_10, - MIO_INSTANCE_11, - MIO_INSTANCE_12, - MIO_INSTANCE_13, - MIO_INSTANCE_14, - MIO_INSTANCE_15, + FMIO0_ID = 0, + FMIO1_ID = 1, + FMIO2_ID, + FMIO3_ID, + FMIO4_ID, + FMIO5_ID, + FMIO6_ID, + FMIO7_ID, + FMIO8_ID, + FMIO9_ID, + FMIO10_ID, + FMIO11_ID, + FMIO12_ID, + FMIO13_ID, + FMIO14_ID, + FMIO15_ID, - MIO_INSTANCE_NUM -} MioInstance; + FMIO_NUM +}; #endif #if !defined(__ASSEMBLER__) @@ -435,49 +454,49 @@ typedef enum * I2C1 -> PMBUS1 * I2C2 -> SMBUS0 */ -typedef enum +enum { - I2C_INSTANCE_0 = 0, - I2C_INSTANCE_1, - I2C_INSTANCE_2, + FI2C0_ID = 0, + FI2C1_ID, + FI2C2_ID, - I2C_INSTANCE_NUM -} I2cInstance; + FI2C_NUM +}; #endif -#define I2C_0_BASEADDR 0x28011000 -#define I2C_1_BASEADDR 0x28012000 -#define I2C_2_BASEADDR 0x28013000 +#define FI2C0_BASE_ADDR 0x28011000 +#define FI2C1_BASE_ADDR 0x28012000 +#define FI2C2_BASE_ADDR 0x28013000 -#define I2C_0_INTR_IRQ 121 -#define I2C_1_INTR_IRQ 122 -#define I2C_2_INTR_IRQ 123 +#define FI2C0_IRQ_NUM 121 +#define FI2C1_IRQ_NUM 122 +#define FI2C2_IRQ_NUM 123 -#define I2C_REF_CLK_HZ 50000000 /* 50MHz */ +#define FI2C_CLK_FREQ_HZ 50000000 /* 50MHz */ /* SDIO */ #if !defined(__ASSEMBLER__) enum { - FSDIO_HOST_INSTANCE_0 = 0, - FSDIO_HOST_INSTANCE_1, + FSDIO0_ID = 0, + FSDIO1_ID = 1, - FSDIO_HOST_INSTANCE_NUM + FSDIO_NUM }; #endif -#define FSDIO_HOST_0_BASE_ADDR 0x28000000U -#define FSDIO_HOST_1_BASE_ADDR 0x28001000U +#define FSDIO0_BASE_ADDR 0x28000000U +#define FSDIO1_BASE_ADDR 0x28001000U -#define FSDIO_HOST_0_IRQ_NUM 104U -#define FSDIO_HOST_1_IRQ_NUM 105U +#define FSDIO0_IRQ_NUM 104U +#define FSDIO1_IRQ_NUM 105U -#define FSDIO_CLK_RATE_HZ (1200000000UL) /* 1.2GHz */ +#define FSDIO_CLK_FREQ_HZ (1200000000UL) /* 1.2GHz */ /* NAND */ #define FNAND_NUM 1U #define FNAND_INSTANCE0 0U -#define FNAND_BASEADDRESS 0x28002000U +#define FNAND_BASE_ADDR 0x28002000U #define FNAND_IRQ_NUM (106U) #define FNAND_CONNECT_MAX_NUM 1U @@ -519,13 +538,12 @@ enum /* ADC */ #if !defined(__ASSEMBLER__) -typedef enum +enum { - FADC_INSTANCE_0 = 0, - FADC_INSTANCE_1, + FADC0_ID = 0, - FADC_INSTANCE_NUM -} FAdcInstance; + FADC_NUM +}; typedef enum { @@ -543,27 +561,25 @@ typedef enum #endif -#define FADC0_CONTROL_BASE 0x2807B000U -#define FADC1_CONTROL_BASE 0x2807C000U +#define FADC0_BASE_ADDR 0x2807B000U -#define FADC0_INTR_IRQ 264U -#define FADC1_INTR_IRQ 265U +#define FADC0_IRQ_NUM 264U /* PWM */ #if !defined(__ASSEMBLER__) -typedef enum +enum { - FPWM_INSTANCE_0 = 0, - FPWM_INSTANCE_1, - FPWM_INSTANCE_2, - FPWM_INSTANCE_3, - FPWM_INSTANCE_4, - FPWM_INSTANCE_5, - FPWM_INSTANCE_6, - FPWM_INSTANCE_7, + FPWM0_ID = 0, + FPWM1_ID = 1, + FPWM2_ID, + FPWM3_ID, + FPWM4_ID, + FPWM5_ID, + FPWM6_ID, + FPWM7_ID, - FPWM_INSTANCE_NUM -} FPwmInstance; + FPWM_NUM +}; typedef enum { @@ -574,26 +590,26 @@ typedef enum } FPwmChannel; #endif -#define FPWM_CONTROL_BASE 0x2804A000U +#define FPWM_BASE_ADDR 0x2804A000U -#define FPWM_CLK 50000000U /* 50MHz */ +#define FPWM_CLK_FREQ_HZ 50000000U /* 50MHz */ -#define FPWM0_INTR_IRQ 205U -#define FPWM1_INTR_IRQ 206U -#define FPWM2_INTR_IRQ 207U -#define FPWM3_INTR_IRQ 208U -#define FPWM4_INTR_IRQ 209U -#define FPWM5_INTR_IRQ 210U -#define FPWM6_INTR_IRQ 211U -#define FPWM7_INTR_IRQ 212U -#define FPWM8_INTR_IRQ 213U -#define FPWM9_INTR_IRQ 214U -#define FPWM10_INTR_IRQ 215U -#define FPWM11_INTR_IRQ 216U -#define FPWM12_INTR_IRQ 217U -#define FPWM13_INTR_IRQ 218U -#define FPWM14_INTR_IRQ 219U -#define FPWM15_INTR_IRQ 220U +#define FPWM0_IRQ_NUM 205U +#define FPWM1_IRQ_NUM 206U +#define FPWM2_IRQ_NUM 207U +#define FPWM3_IRQ_NUM 208U +#define FPWM4_IRQ_NUM 209U +#define FPWM5_IRQ_NUM 210U +#define FPWM6_IRQ_NUM 211U +#define FPWM7_IRQ_NUM 212U +#define FPWM8_IRQ_NUM 213U +#define FPWM9_IRQ_NUM 214U +#define FPWM10_IRQ_NUM 215U +#define FPWM11_IRQ_NUM 216U +#define FPWM12_IRQ_NUM 217U +#define FPWM13_IRQ_NUM 218U +#define FPWM14_IRQ_NUM 219U +#define FPWM15_IRQ_NUM 220U /* Semaphore */ #define FSEMA0_ID 0U @@ -606,14 +622,41 @@ typedef enum #define FLSD_CK_STOP_CONFIG0_HADDR 0x10U /* USB3 */ -#define FUSB3_ID_0 0U -#define FUSB3_ID_1 1U -#define FUSB3_NUM 2U -#define FUSB3_XHCI_OFFSET 0x8000U -#define FUSB3_0_BASE_ADDR 0x31A00000U -#define FUSB3_1_BASE_ADDR 0x31A20000U -#define FUSB3_0_IRQ_NUM 48U -#define FUSB3_1_IRQ_NUM 49U +#define FUSB3_ID_0 0U +#define FUSB3_ID_1 1U +#define FUSB3_NUM 2U +#define FUSB3_XHCI_OFFSET 0x8000U +#define FUSB3_0_BASE_ADDR 0x31A00000U +#define FUSB3_1_BASE_ADDR 0x31A20000U +#define FUSB3_0_IRQ_NUM 48U +#define FUSB3_1_IRQ_NUM 49U + +/* DcDp */ +#if !defined(__ASSEMBLER__) + +typedef enum +{ + FDCDP_ID0 = 0, + FDCDP_ID1, + + FDCDP_INSTANCE_NUM +} FDcDpNum; + +#endif + +#define FDC_CTRL_BASE_OFFSET 0x32000000U + +#define FDC0_CHANNEL_BASE_OFFSET 0x32001000U +#define FDC1_CHANNEL_BASE_OFFSET (FDC0_CHANNEL_BASE_OFFSET + 0x1000U) + +#define FDP0_CHANNEL_BASE_OFFSET 0x32004000U +#define FDP1_CHANNEL_BASE_OFFSET (FDP0_CHANNEL_BASE_OFFSET + 0x1000U) + +#define FDP0_PHY_BASE_OFFSET 0x32300000U +#define FDP1_PHY_BASE_OFFSET (FDP0_PHY_BASE_OFFSET + 0x100000U) + +#define FDCDP_IRQ_NUM 76 + /*****************************************************************************/ #ifdef __cplusplus diff --git a/bsp/phytium/libraries/standalone/board/e2000/q/fiopad_config.c b/bsp/phytium/libraries/standalone/board/e2000/q/fiopad_config.c index b29a9e0a2b..c60770ce71 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/q/fiopad_config.c +++ b/bsp/phytium/libraries/standalone/board/e2000/q/fiopad_config.c @@ -14,7 +14,7 @@ * FilePath: fiopad_config.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for io-pad function definition + * Description:  This file is for io-pad function definition * * Modify History: * Ver   Who        Date         Changes @@ -93,6 +93,17 @@ void FIOPadSetSpimMux(u32 spim_id) } } +static void FIOPadDumpGpioPin(FPinIndex pin, u32 gpio_id, u32 pin_id) +{ + FPinFunc func = FPIN_FUNC0; + FPinPull pull = FPIN_PULL_NONE; + FPinDrive drive = FPIN_DRV0; + + FPinGetConfig(pin, &func, &pull, &drive); + FIOPAD_DEBUG("GPIO-%d-%d: func: %d, pull: %d, drive: %d", + gpio_id, pin_id, func, pull, drive); +} + /** * @name: FIOPadSetGpioMux * @msg: set iopad mux for gpio @@ -102,59 +113,71 @@ void FIOPadSetSpimMux(u32 spim_id) */ void FIOPadSetGpioMux(u32 gpio_id, u32 pin_id) { - if (FGPIO_ID_2 == gpio_id) + if (FGPIO2_ID == gpio_id) { switch (pin_id) { - case 11: /* gpio 2-a-11 */ - FPinSetFunc(FIOPAD_N49, FPIN_FUNC0); - break; - case 12: /* gpio 2-a-12 */ - FPinSetFunc(FIOPAD_L51, FPIN_FUNC0); - break; - case 13: /* gpio 2-a-13 */ - FPinSetFunc(FIOPAD_L49, FPIN_FUNC0); - break; - case 14: /* gpio 2-a-14 */ - FPinSetFunc(FIOPAD_N53, FPIN_FUNC0); - break; - case 15: /* gpio 2-a-15 */ - FPinSetFunc(FIOPAD_J53, FPIN_FUNC0); - break; + case 11: /* gpio 2-a-11 */ + FPinSetFunc(FIOPAD_N49, FPIN_FUNC0); + break; + case 12: /* gpio 2-a-12 */ + FPinSetFunc(FIOPAD_L51, FPIN_FUNC0); + break; + case 13: /* gpio 2-a-13 */ + FPinSetFunc(FIOPAD_L49, FPIN_FUNC0); + break; + case 14: /* gpio 2-a-14 */ + FPinSetFunc(FIOPAD_N53, FPIN_FUNC0); + break; + case 15: /* gpio 2-a-15 */ + FPinSetFunc(FIOPAD_J53, FPIN_FUNC0); + break; } } - else if (FGPIO_ID_3 == gpio_id) + else if (FGPIO3_ID == gpio_id) { switch (pin_id) { - case 3: /* gpio 3-a-3 */ - FPinSetFunc(FIOPAD_A33, FPIN_FUNC6); - break; - case 4: /* gpio 3-a-4 */ - FPinSetFunc(FIOPAD_C33, FPIN_FUNC6); - break; - case 5: /* gpio 3-a-5 */ - FPinSetFunc(FIOPAD_C31, FPIN_FUNC6); - break; - case 6: /* gpio 3-a-6 */ - FPinSetFunc(FIOPAD_A31, FPIN_FUNC6); - break; - default: - break; + case 3: /* gpio 3-a-3 */ + FPinSetFunc(FIOPAD_A33, FPIN_FUNC6); + break; + case 4: /* gpio 3-a-4 */ + FPinSetFunc(FIOPAD_C33, FPIN_FUNC6); + break; + case 5: /* gpio 3-a-5 */ + FPinSetFunc(FIOPAD_C31, FPIN_FUNC6); + break; + case 6: /* gpio 3-a-6 */ + FPinSetFunc(FIOPAD_A31, FPIN_FUNC6); + break; + default: + break; } } - else if (FGPIO_ID_4 == gpio_id) + else if (FGPIO4_ID == gpio_id) { switch (pin_id) { - case 5: /* gpio 4-a-5 */ - FPinSetFunc(FIOPAD_W51, FPIN_FUNC6); - break; - case 9: /* gpio 4-a-9 */ - FPinSetFunc(FIOPAD_U53, FPIN_FUNC6); - break; - default: - break; + case 5: /* gpio 4-a-5 */ + FPinSetFunc(FIOPAD_W51, FPIN_FUNC6); + break; + case 9: /* gpio 4-a-9 */ + FPinSetFunc(FIOPAD_U53, FPIN_FUNC6); + break; + case 10: /* gpio 4-a-10 */ + FPinSetFunc(FIOPAD_AE49, FPIN_FUNC6); + break; + case 11: /* gpio 4-a-11 */ + FPinSetFunc(FIOPAD_AC49, FPIN_FUNC6); + break; + case 12: /* gpio 4-a-12 */ + FPinSetFunc(FIOPAD_AE47, FPIN_FUNC6); + break; + case 13: /* gpio 4-a-13 */ + FPinSetFunc(FIOPAD_AA47, FPIN_FUNC6); + break; + default: + break; } } } @@ -168,15 +191,15 @@ void FIOPadSetGpioMux(u32 gpio_id, u32 pin_id) */ void FIOPadSetCanMux(u32 can_id) { - if (can_id == FCAN_INSTANCE_0) + if (can_id == FCAN0_ID) { - /* mio0 */ + /* can0 */ FPinSetFunc(FIOPAD_A41, FPIN_FUNC0); /* can0-tx: func 0 */ FPinSetFunc(FIOPAD_A43, FPIN_FUNC0); /* can0-rx: func 0 */ } - else if (can_id == FCAN_INSTANCE_1) + else if (can_id == FCAN1_ID) { - /* mio1 */ + /* can1 */ FPinSetFunc(FIOPAD_A45, FPIN_FUNC0); /* can1-tx: func 0 */ FPinSetFunc(FIOPAD_C45, FPIN_FUNC0); /* can1-rx: func 0 */ } @@ -196,7 +219,7 @@ void FIOPadSetCanMux(u32 can_id) void FIOPadSetQspiMux(u32 qspi_id, u32 cs_id) { - if (qspi_id == FQSPI_INSTANCE_0) + if (qspi_id == FQSPI0_ID) { /* add sck, io0-io3 iopad multiplex */ } @@ -232,102 +255,102 @@ void FIOPadSetQspiMux(u32 qspi_id, u32 cs_id) */ void FIOPadSetPwmMux(u32 pwm_id, u32 pwm_channel) { - FASSERT(pwm_id < FPWM_INSTANCE_NUM); + FASSERT(pwm_id < FPWM_NUM); FASSERT(pwm_channel < FPWM_CHANNEL_NUM); switch (pwm_id) { - case FPWM_INSTANCE_0: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_AL59, FPIN_FUNC1); /* PWM0_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_AJ57, FPIN_FUNC1); /* PWM1_OUT: func 1 */ - } - break; + case FPWM0_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_AL59, FPIN_FUNC1); /* PWM0_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_AJ57, FPIN_FUNC1); /* PWM1_OUT: func 1 */ + } + break; - case FPWM_INSTANCE_1: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_AG57, FPIN_FUNC1); /* PWM2_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_AC59, FPIN_FUNC1); /* PWM3_OUT: func 1 */ - } - break; + case FPWM1_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_AG57, FPIN_FUNC1); /* PWM2_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_AC59, FPIN_FUNC1); /* PWM3_OUT: func 1 */ + } + break; - case FPWM_INSTANCE_2: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_BA55, FPIN_FUNC1); /* PWM4_OUT: func 1 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C39, FPIN_FUNC2); /* PWM5_OUT: func 2 */ - } - break; + case FPWM2_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_BA55, FPIN_FUNC1); /* PWM4_OUT: func 1 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C39, FPIN_FUNC2); /* PWM5_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_3: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); /* PWM6_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); /* PWM7_OUT: func 2 */ - } - break; + case FPWM3_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); /* PWM6_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); /* PWM7_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_4: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); /* PWM8_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_A49, FPIN_FUNC2); /* PWM9_OUT: func 2 */ - } - break; + case FPWM4_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); /* PWM8_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_A49, FPIN_FUNC2); /* PWM9_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_5: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A51, FPIN_FUNC2); /* PWM10_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); /* PWM11_OUT: func 2 */ - } - break; + case FPWM5_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A51, FPIN_FUNC2); /* PWM10_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); /* PWM11_OUT: func 2 */ + } + break; - case FPWM_INSTANCE_6: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_A31, FPIN_FUNC2); /* PWM12_OUT: func 2 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_J39, FPIN_FUNC3); /* PWM13_OUT: func 3 */ - } - break; + case FPWM6_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_A31, FPIN_FUNC2); /* PWM12_OUT: func 2 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_J39, FPIN_FUNC3); /* PWM13_OUT: func 3 */ + } + break; - case FPWM_INSTANCE_7: - if (pwm_channel == 0) - { - FPinSetFunc(FIOPAD_E43, FPIN_FUNC3); /* PWM14_OUT: func 3 */ - } - if (pwm_channel == 1) - { - FPinSetFunc(FIOPAD_C43, FPIN_FUNC3); /* PWM15_OUT: func 3 */ - } - break; + case FPWM7_ID: + if (pwm_channel == 0) + { + FPinSetFunc(FIOPAD_E43, FPIN_FUNC3); /* PWM14_OUT: func 3 */ + } + if (pwm_channel == 1) + { + FPinSetFunc(FIOPAD_C43, FPIN_FUNC3); /* PWM15_OUT: func 3 */ + } + break; - default: - FIOPAD_ERROR("pwm id is error.\r\n"); - break; + default: + FIOPAD_ERROR("pwm id is error.\r\n"); + break; } } @@ -341,70 +364,37 @@ void FIOPadSetPwmMux(u32 pwm_id, u32 pwm_channel) */ void FIOPadSetAdcMux(u32 adc_id, u32 adc_channel) { - if (adc_id == FADC_INSTANCE_0) + if (adc_id == FADC0_ID) { switch (adc_channel) { - case FADC_CHANNEL_0: - FPinSetFunc(FIOPAD_R51, FPIN_FUNC7); /* adc0-0: func 7 */ - break; - case FADC_CHANNEL_1: - FPinSetFunc(FIOPAD_R49, FPIN_FUNC7); /* adc0-1: func 7 */ - break; - case FADC_CHANNEL_2: - FPinSetFunc(FIOPAD_N51, FPIN_FUNC7); /* adc0-2: func 7 */ - break; - case FADC_CHANNEL_3: - FPinSetFunc(FIOPAD_N55, FPIN_FUNC7); /* adc0-3: func 7 */ - break; - case FADC_CHANNEL_4: - FPinSetFunc(FIOPAD_L55, FPIN_FUNC7); /* adc0-4: func 7 */ - break; - case FADC_CHANNEL_5: - FPinSetFunc(FIOPAD_J55, FPIN_FUNC7); /* adc0-5: func 7 */ - break; - case FADC_CHANNEL_6: - FPinSetFunc(FIOPAD_J45, FPIN_FUNC7); /* adc0-6: func 7 */ - break; - case FADC_CHANNEL_7: - FPinSetFunc(FIOPAD_E47, FPIN_FUNC7); /* adc0-7: func 7 */ - break; - default: - FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); - break; - } - } - else if (adc_id == FADC_INSTANCE_1) - { - switch (adc_channel) - { - case FADC_CHANNEL_0: - FPinSetFunc(FIOPAD_G47, FPIN_FUNC7); /* adc1-0: func 7 */ - break; - case FADC_CHANNEL_1: - FPinSetFunc(FIOPAD_J47, FPIN_FUNC7); /* adc1-1: func 7 */ - break; - case FADC_CHANNEL_2: - FPinSetFunc(FIOPAD_J49, FPIN_FUNC7); /* adc1-2: func 7 */ - break; - case FADC_CHANNEL_3: - FPinSetFunc(FIOPAD_N49, FPIN_FUNC7); /* adc1-3: func 7 */ - break; - case FADC_CHANNEL_4: - FPinSetFunc(FIOPAD_L51, FPIN_FUNC7); /* adc1-4: func 7 */ - break; - case FADC_CHANNEL_5: - FPinSetFunc(FIOPAD_L49, FPIN_FUNC7); /* adc1-5: func 7 */ - break; - case FADC_CHANNEL_6: - FPinSetFunc(FIOPAD_N53, FPIN_FUNC7); /* adc1-6: func 7 */ - break; - case FADC_CHANNEL_7: - FPinSetFunc(FIOPAD_J53, FPIN_FUNC7); /* adc1-7: func 7 */ - break; - default: - FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); - break; + case FADC_CHANNEL_0: + FPinSetFunc(FIOPAD_R51, FPIN_FUNC7); /* adc0-0: func 7 */ + break; + case FADC_CHANNEL_1: + FPinSetFunc(FIOPAD_R49, FPIN_FUNC7); /* adc0-1: func 7 */ + break; + case FADC_CHANNEL_2: + FPinSetFunc(FIOPAD_N51, FPIN_FUNC7); /* adc0-2: func 7 */ + break; + case FADC_CHANNEL_3: + FPinSetFunc(FIOPAD_N55, FPIN_FUNC7); /* adc0-3: func 7 */ + break; + case FADC_CHANNEL_4: + FPinSetFunc(FIOPAD_L55, FPIN_FUNC7); /* adc0-4: func 7 */ + break; + case FADC_CHANNEL_5: + FPinSetFunc(FIOPAD_J55, FPIN_FUNC7); /* adc0-5: func 7 */ + break; + case FADC_CHANNEL_6: + FPinSetFunc(FIOPAD_J45, FPIN_FUNC7); /* adc0-6: func 7 */ + break; + case FADC_CHANNEL_7: + FPinSetFunc(FIOPAD_E47, FPIN_FUNC7); /* adc0-7: func 7 */ + break; + default: + FIOPAD_ERROR("adc %d channel %d is error.\r\n", adc_id, adc_channel); + break; } } else @@ -423,104 +413,104 @@ void FIOPadSetMioMux(u32 mio_id) { switch (mio_id) { - case MIO_INSTANCE_0: - { - FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_1: - { - FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_2: - { - FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A49, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_3: - { - FPinSetFunc(FIOPAD_BA55, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_BA53, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_4: - { - FPinSetFunc(FIOPAD_R59, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U59, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_5: - { - FPinSetFunc(FIOPAD_W49, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U57, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_6: - { - FPinSetFunc(FIOPAD_AA57, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_AA59, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_7: - { - FPinSetFunc(FIOPAD_A39, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_C39, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_8: - { - FPinSetFunc(FIOPAD_AA49, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_W49, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_9: - { - FPinSetFunc(FIOPAD_AA51, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U49, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_10: - { - FPinSetFunc(FIOPAD_C49, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A51, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_11: - { - FPinSetFunc(FIOPAD_N27, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L29, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_12: - { - FPinSetFunc(FIOPAD_E41, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L45, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_13: - { - FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_14: - { - FPinSetFunc(FIOPAD_L51, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_L49, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_15: - { - FPinSetFunc(FIOPAD_N53, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_J53, FPIN_FUNC6); /* sda */ - } - break; - default: + case FMIO0_ID: + { + FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* sda */ + } break; + case FMIO1_ID: + { + FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* sda */ + } + break; + case FMIO2_ID: + { + FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A49, FPIN_FUNC5); /* sda */ + } + break; + case FMIO3_ID: + { + FPinSetFunc(FIOPAD_BA55, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_BA53, FPIN_FUNC4); /* sda */ + } + break; + case FMIO4_ID: + { + FPinSetFunc(FIOPAD_R59, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U59, FPIN_FUNC4); /* sda */ + } + break; + case FMIO5_ID: + { + FPinSetFunc(FIOPAD_W49, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U57, FPIN_FUNC4); /* sda */ + } + break; + case FMIO6_ID: + { + FPinSetFunc(FIOPAD_AA57, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_AA59, FPIN_FUNC4); /* sda */ + } + break; + case FMIO7_ID: + { + FPinSetFunc(FIOPAD_A39, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_C39, FPIN_FUNC4); /* sda */ + } + break; + case FMIO8_ID: + { + FPinSetFunc(FIOPAD_AA49, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_W49, FPIN_FUNC4); /* sda */ + } + break; + case FMIO9_ID: + { + FPinSetFunc(FIOPAD_AA51, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U49, FPIN_FUNC4); /* sda */ + } + break; + case FMIO10_ID: + { + FPinSetFunc(FIOPAD_C49, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A51, FPIN_FUNC5); /* sda */ + } + break; + case FMIO11_ID: + { + FPinSetFunc(FIOPAD_N27, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L29, FPIN_FUNC3); /* sda */ + } + break; + case FMIO12_ID: + { + FPinSetFunc(FIOPAD_E41, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L45, FPIN_FUNC3); /* sda */ + } + break; + case FMIO13_ID: + { + FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* sda */ + } + break; + case FMIO14_ID: + { + FPinSetFunc(FIOPAD_L51, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_L49, FPIN_FUNC6); /* sda */ + } + break; + case FMIO15_ID: + { + FPinSetFunc(FIOPAD_N53, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_J53, FPIN_FUNC6); /* sda */ + } + break; + default: + break; } } @@ -534,56 +524,56 @@ void FIOPadSetTachoMux(u32 pwm_in_id) { switch (pwm_in_id) { - case TACHO_INSTANCE_0: - FPinSetFunc(FIOPAD_AN57, FPIN_FUNC1); - break; - case TACHO_INSTANCE_1: - FPinSetFunc(FIOPAD_AJ59, FPIN_FUNC1); - break; - case TACHO_INSTANCE_2: - FPinSetFunc(FIOPAD_AG59, FPIN_FUNC1); - break; - case TACHO_INSTANCE_3: - FPinSetFunc(FIOPAD_AE59, FPIN_FUNC1); - break; - case TACHO_INSTANCE_4: - FPinSetFunc(FIOPAD_AC57, FPIN_FUNC1); - break; - case TACHO_INSTANCE_5: - FPinSetFunc(FIOPAD_BA53, FPIN_FUNC1); - break; - case TACHO_INSTANCE_6: - FPinSetFunc(FIOPAD_C37, FPIN_FUNC2); - break; - case TACHO_INSTANCE_7: - FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); - break; - case TACHO_INSTANCE_8: - FPinSetFunc(FIOPAD_A45, FPIN_FUNC2); - break; - case TACHO_INSTANCE_9: - FPinSetFunc(FIOPAD_A47, FPIN_FUNC2); - break; - case TACHO_INSTANCE_10: - FPinSetFunc(FIOPAD_C49, FPIN_FUNC2); - break; - case TACHO_INSTANCE_11: - FPinSetFunc(FIOPAD_A33, FPIN_FUNC2); - break; - case TACHO_INSTANCE_12: - FPinSetFunc(FIOPAD_C31, FPIN_FUNC2); - break; - case TACHO_INSTANCE_13: - FPinSetFunc(FIOPAD_AA49, FPIN_FUNC2); - break; - case TACHO_INSTANCE_14: - FPinSetFunc(FIOPAD_AA51, FPIN_FUNC2); - break; - case TACHO_INSTANCE_15: - FPinSetFunc(FIOPAD_G59, FPIN_FUNC2); - break; - default: - break; + case FTACHO0_ID: + FPinSetFunc(FIOPAD_AN57, FPIN_FUNC1); + break; + case FTACHO1_ID: + FPinSetFunc(FIOPAD_AJ59, FPIN_FUNC1); + break; + case FTACHO2_ID: + FPinSetFunc(FIOPAD_AG59, FPIN_FUNC1); + break; + case FTACHO3_ID: + FPinSetFunc(FIOPAD_AE59, FPIN_FUNC1); + break; + case FTACHO4_ID: + FPinSetFunc(FIOPAD_AC57, FPIN_FUNC1); + break; + case FTACHO5_ID: + FPinSetFunc(FIOPAD_BA53, FPIN_FUNC1); + break; + case FTACHO6_ID: + FPinSetFunc(FIOPAD_C37, FPIN_FUNC2); + break; + case FTACHO7_ID: + FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); + break; + case FTACHO8_ID: + FPinSetFunc(FIOPAD_A45, FPIN_FUNC2); + break; + case FTACHO9_ID: + FPinSetFunc(FIOPAD_A47, FPIN_FUNC2); + break; + case FTACHO10_ID: + FPinSetFunc(FIOPAD_C49, FPIN_FUNC2); + break; + case FTACHO11_ID: + FPinSetFunc(FIOPAD_A33, FPIN_FUNC2); + break; + case FTACHO12_ID: + FPinSetFunc(FIOPAD_C31, FPIN_FUNC2); + break; + case FTACHO13_ID: + FPinSetFunc(FIOPAD_AA49, FPIN_FUNC2); + break; + case FTACHO14_ID: + FPinSetFunc(FIOPAD_AA51, FPIN_FUNC2); + break; + case FTACHO15_ID: + FPinSetFunc(FIOPAD_G59, FPIN_FUNC2); + break; + default: + break; } } @@ -597,23 +587,23 @@ void FIOPadSetUartMux(u32 uart_id) { switch (uart_id) { - case FUART0_ID: - FPinSetFunc(FIOPAD_J37, FPIN_FUNC4); - FPinSetFunc(FIOPAD_J39, FPIN_FUNC4); - break; - case FUART1_ID: - FPinSetFunc(FIOPAD_AW51, FPIN_FUNC0); - FPinSetFunc(FIOPAD_AU51, FPIN_FUNC0); - break; - case FUART2_ID: - FPinSetFunc(FIOPAD_A47, FPIN_FUNC0); - FPinSetFunc(FIOPAD_A49, FPIN_FUNC0); - break; - case FUART3_ID: - FPinSetFunc(FIOPAD_L37, FPIN_FUNC2); - FPinSetFunc(FIOPAD_N35, FPIN_FUNC2); - break; - default: - break; + case FUART0_ID: + FPinSetFunc(FIOPAD_J37, FPIN_FUNC4); + FPinSetFunc(FIOPAD_J39, FPIN_FUNC4); + break; + case FUART1_ID: + FPinSetFunc(FIOPAD_AW51, FPIN_FUNC0); + FPinSetFunc(FIOPAD_AU51, FPIN_FUNC0); + break; + case FUART2_ID: + FPinSetFunc(FIOPAD_A47, FPIN_FUNC0); + FPinSetFunc(FIOPAD_A49, FPIN_FUNC0); + break; + case FUART3_ID: + FPinSetFunc(FIOPAD_L37, FPIN_FUNC2); + FPinSetFunc(FIOPAD_N35, FPIN_FUNC2); + break; + default: + break; } } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/e2000/q/fparameters.h b/bsp/phytium/libraries/standalone/board/e2000/q/fparameters.h index 9d7a5691e8..680ba76b2d 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/q/fparameters.h +++ b/bsp/phytium/libraries/standalone/board/e2000/q/fparameters.h @@ -14,7 +14,7 @@ * FilePath: fparameters.h * Date: 2022-02-11 13:33:28 * LastEditTime: 2022-02-17 18:00:50 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/board/e2000/s/fiopad_config.c b/bsp/phytium/libraries/standalone/board/e2000/s/fiopad_config.c index 8ab06f4837..ac4fb903af 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/s/fiopad_config.c +++ b/bsp/phytium/libraries/standalone/board/e2000/s/fiopad_config.c @@ -14,7 +14,7 @@ * FilePath: fiopad_config.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for io-pad function definition + * Description:  This file is for io-pad function definition * * Modify History: * Ver   Who        Date         Changes @@ -63,24 +63,50 @@ void FIOPadSetSpimMux(u32 spim_id) */ void FIOPadSetGpioMux(u32 gpio_id, u32 pin_id) { - if (FGPIO_ID_3 == gpio_id) + if (FGPIO3_ID == gpio_id) { switch (pin_id) { - case 3: /* gpio 3-a-3 */ - FPinSetFunc(FIOPAD_A29, FPIN_FUNC6); - break; - case 4: /* gpio 3-a-4 */ - FPinSetFunc(FIOPAD_C29, FPIN_FUNC6); - break; - case 5: /* gpio 3-a-5 */ - FPinSetFunc(FIOPAD_C27, FPIN_FUNC6); - break; - case 6: /* gpio 3-a-6 */ - FPinSetFunc(FIOPAD_A27, FPIN_FUNC6); - break; - default: - break; + case 3: /* gpio 3-a-3 */ + FPinSetFunc(FIOPAD_A29, FPIN_FUNC6); + break; + case 4: /* gpio 3-a-4 */ + FPinSetFunc(FIOPAD_C29, FPIN_FUNC6); + break; + case 5: /* gpio 3-a-5 */ + FPinSetFunc(FIOPAD_C27, FPIN_FUNC6); + break; + case 6: /* gpio 3-a-6 */ + FPinSetFunc(FIOPAD_A27, FPIN_FUNC6); + break; + default: + break; + } + } + else if (FGPIO4_ID == gpio_id) + { + switch (pin_id) + { + case 5: /* gpio 4-a-5 */ + FPinSetFunc(FIOPAD_W47, FPIN_FUNC6); + break; + case 9: /* gpio 4-a-9 */ + FPinSetFunc(FIOPAD_U49, FPIN_FUNC6); + break; + case 10: /* gpio 4-a-10 */ + FPinSetFunc(FIOPAD_AE45, FPIN_FUNC6); + break; + case 11: /* gpio 4-a-11 */ + FPinSetFunc(FIOPAD_AC45, FPIN_FUNC6); + break; + case 12: /* gpio 4-a-12 */ + FPinSetFunc(FIOPAD_AE43, FPIN_FUNC6); + break; + case 13: /* gpio 4-a-13 */ + FPinSetFunc(FIOPAD_AA43, FPIN_FUNC6); + break; + default: + break; } } } @@ -95,104 +121,104 @@ void FIOPadSetMioMux(u32 mio_id) { switch (mio_id) { - case MIO_INSTANCE_0: - { - FPinSetFunc(FIOPAD_A37, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A39, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_1: - { - FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_C41, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_2: - { - FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_3: - { - FPinSetFunc(FIOPAD_BA51, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_BA49, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_4: - { - FPinSetFunc(FIOPAD_R55, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U55, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_5: - { - FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U53, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_6: - { - FPinSetFunc(FIOPAD_AA53, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_AA55, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_7: - { - FPinSetFunc(FIOPAD_A35, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_C35, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_8: - { - FPinSetFunc(FIOPAD_AA45, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_9: - { - FPinSetFunc(FIOPAD_AA47, FPIN_FUNC4); /* scl */ - FPinSetFunc(FIOPAD_U45, FPIN_FUNC4); /* sda */ - } - break; - case MIO_INSTANCE_10: - { - FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* scl */ - FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* sda */ - } - break; - case MIO_INSTANCE_11: - { - FPinSetFunc(FIOPAD_N23, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L25, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_12: - { - FPinSetFunc(FIOPAD_E37, FPIN_FUNC3); /* scl */ - FPinSetFunc(FIOPAD_L41, FPIN_FUNC3); /* sda */ - } - break; - case MIO_INSTANCE_13: - { - FPinSetFunc(FIOPAD_J45, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_N45, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_14: - { - FPinSetFunc(FIOPAD_L47, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_L45, FPIN_FUNC6); /* sda */ - } - break; - case MIO_INSTANCE_15: - { - FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* scl */ - FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* sda */ - } - break; - default: + case FMIO0_ID: + { + FPinSetFunc(FIOPAD_A37, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A39, FPIN_FUNC5); /* sda */ + } break; + case FMIO1_ID: + { + FPinSetFunc(FIOPAD_A41, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_C41, FPIN_FUNC5); /* sda */ + } + break; + case FMIO2_ID: + { + FPinSetFunc(FIOPAD_A43, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A45, FPIN_FUNC5); /* sda */ + } + break; + case FMIO3_ID: + { + FPinSetFunc(FIOPAD_BA51, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_BA49, FPIN_FUNC4); /* sda */ + } + break; + case FMIO4_ID: + { + FPinSetFunc(FIOPAD_R55, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U55, FPIN_FUNC4); /* sda */ + } + break; + case FMIO5_ID: + { + FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U53, FPIN_FUNC4); /* sda */ + } + break; + case FMIO6_ID: + { + FPinSetFunc(FIOPAD_AA53, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_AA55, FPIN_FUNC4); /* sda */ + } + break; + case FMIO7_ID: + { + FPinSetFunc(FIOPAD_A35, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_C35, FPIN_FUNC4); /* sda */ + } + break; + case FMIO8_ID: + { + FPinSetFunc(FIOPAD_AA45, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_W45, FPIN_FUNC4); /* sda */ + } + break; + case FMIO9_ID: + { + FPinSetFunc(FIOPAD_AA47, FPIN_FUNC4); /* scl */ + FPinSetFunc(FIOPAD_U45, FPIN_FUNC4); /* sda */ + } + break; + case FMIO10_ID: + { + FPinSetFunc(FIOPAD_C45, FPIN_FUNC5); /* scl */ + FPinSetFunc(FIOPAD_A47, FPIN_FUNC5); /* sda */ + } + break; + case FMIO11_ID: + { + FPinSetFunc(FIOPAD_N23, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L25, FPIN_FUNC3); /* sda */ + } + break; + case FMIO12_ID: + { + FPinSetFunc(FIOPAD_E37, FPIN_FUNC3); /* scl */ + FPinSetFunc(FIOPAD_L41, FPIN_FUNC3); /* sda */ + } + break; + case FMIO13_ID: + { + FPinSetFunc(FIOPAD_J45, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_N45, FPIN_FUNC6); /* sda */ + } + break; + case FMIO14_ID: + { + FPinSetFunc(FIOPAD_L47, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_L45, FPIN_FUNC6); /* sda */ + } + break; + case FMIO15_ID: + { + FPinSetFunc(FIOPAD_N49, FPIN_FUNC6); /* scl */ + FPinSetFunc(FIOPAD_J49, FPIN_FUNC6); /* sda */ + } + break; + default: + break; } } @@ -206,56 +232,56 @@ void FIOPadSetTachoMux(u32 pwm_in_id) { switch (pwm_in_id) { - case TACHO_INSTANCE_0: - FPinSetFunc(FIOPAD_AN53, FPIN_FUNC1); - break; - case TACHO_INSTANCE_1: - FPinSetFunc(FIOPAD_AJ55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_2: - FPinSetFunc(FIOPAD_AG55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_3: - FPinSetFunc(FIOPAD_AE55, FPIN_FUNC1); - break; - case TACHO_INSTANCE_4: - FPinSetFunc(FIOPAD_AC53, FPIN_FUNC1); - break; - case TACHO_INSTANCE_5: - FPinSetFunc(FIOPAD_BA49, FPIN_FUNC1); - break; - case TACHO_INSTANCE_6: - FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); - break; - case TACHO_INSTANCE_7: - FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); - break; - case TACHO_INSTANCE_8: - FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); - break; - case TACHO_INSTANCE_9: - FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); - break; - case TACHO_INSTANCE_10: - FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); - break; - case TACHO_INSTANCE_11: - FPinSetFunc(FIOPAD_A29, FPIN_FUNC2); - break; - case TACHO_INSTANCE_12: - FPinSetFunc(FIOPAD_C27, FPIN_FUNC2); - break; - case TACHO_INSTANCE_13: - FPinSetFunc(FIOPAD_AA45, FPIN_FUNC2); - break; - case TACHO_INSTANCE_14: - FPinSetFunc(FIOPAD_AA47, FPIN_FUNC2); - break; - case TACHO_INSTANCE_15: - FPinSetFunc(FIOPAD_G55, FPIN_FUNC2); - break; - default: - break; + case FTACHO0_ID: + FPinSetFunc(FIOPAD_AN53, FPIN_FUNC1); + break; + case FTACHO1_ID: + FPinSetFunc(FIOPAD_AJ55, FPIN_FUNC1); + break; + case FTACHO2_ID: + FPinSetFunc(FIOPAD_AG55, FPIN_FUNC1); + break; + case FTACHO3_ID: + FPinSetFunc(FIOPAD_AE55, FPIN_FUNC1); + break; + case FTACHO4_ID: + FPinSetFunc(FIOPAD_AC53, FPIN_FUNC1); + break; + case FTACHO5_ID: + FPinSetFunc(FIOPAD_BA49, FPIN_FUNC1); + break; + case FTACHO6_ID: + FPinSetFunc(FIOPAD_C33, FPIN_FUNC2); + break; + case FTACHO7_ID: + FPinSetFunc(FIOPAD_A37, FPIN_FUNC2); + break; + case FTACHO8_ID: + FPinSetFunc(FIOPAD_A41, FPIN_FUNC2); + break; + case FTACHO9_ID: + FPinSetFunc(FIOPAD_A43, FPIN_FUNC2); + break; + case FTACHO10_ID: + FPinSetFunc(FIOPAD_C45, FPIN_FUNC2); + break; + case FTACHO11_ID: + FPinSetFunc(FIOPAD_A29, FPIN_FUNC2); + break; + case FTACHO12_ID: + FPinSetFunc(FIOPAD_C27, FPIN_FUNC2); + break; + case FTACHO13_ID: + FPinSetFunc(FIOPAD_AA45, FPIN_FUNC2); + break; + case FTACHO14_ID: + FPinSetFunc(FIOPAD_AA47, FPIN_FUNC2); + break; + case FTACHO15_ID: + FPinSetFunc(FIOPAD_G55, FPIN_FUNC2); + break; + default: + break; } } @@ -269,23 +295,23 @@ void FIOPadSetUartMux(u32 uart_id) { switch (uart_id) { - case FUART0_ID: - FPinSetFunc(FIOPAD_J33, FPIN_FUNC4); - FPinSetFunc(FIOPAD_J35, FPIN_FUNC4); - break; - case FUART1_ID: - FPinSetFunc(FIOPAD_AW47, FPIN_FUNC0); - FPinSetFunc(FIOPAD_AU47, FPIN_FUNC0); - break; - case FUART2_ID: - FPinSetFunc(FIOPAD_A43, FPIN_FUNC0); - FPinSetFunc(FIOPAD_A45, FPIN_FUNC0); - break; - case FUART3_ID: - FPinSetFunc(FIOPAD_L33, FPIN_FUNC2); - FPinSetFunc(FIOPAD_N31, FPIN_FUNC2); - break; - default: - break; + case FUART0_ID: + FPinSetFunc(FIOPAD_J33, FPIN_FUNC4); + FPinSetFunc(FIOPAD_J35, FPIN_FUNC4); + break; + case FUART1_ID: + FPinSetFunc(FIOPAD_AW47, FPIN_FUNC0); + FPinSetFunc(FIOPAD_AU47, FPIN_FUNC0); + break; + case FUART2_ID: + FPinSetFunc(FIOPAD_A43, FPIN_FUNC0); + FPinSetFunc(FIOPAD_A45, FPIN_FUNC0); + break; + case FUART3_ID: + FPinSetFunc(FIOPAD_L33, FPIN_FUNC2); + FPinSetFunc(FIOPAD_N31, FPIN_FUNC2); + break; + default: + break; } } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/e2000/s/fparameters.h b/bsp/phytium/libraries/standalone/board/e2000/s/fparameters.h index 24b67ac122..4948188f85 100644 --- a/bsp/phytium/libraries/standalone/board/e2000/s/fparameters.h +++ b/bsp/phytium/libraries/standalone/board/e2000/s/fparameters.h @@ -14,7 +14,7 @@ * FilePath: fparameters.h * Date: 2022-02-11 13:33:28 * LastEditTime: 2022-02-17 18:00:50 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.c b/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.c new file mode 100644 index 0000000000..7591b19fad --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.c @@ -0,0 +1,348 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fioctrl.c + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-18 08:25:29 + * Description:  This files is for io-ctrl function implementation (io-mux/io-config/io-delay) + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/2/22 init commit + */ + + +/***************************** Include Files *********************************/ +#include "fparameters.h" +#include "fio.h" +#include "fkernel.h" +#include "fassert.h" +#include "fdebug.h" + +#include "fioctrl.h" +#include "fpinctrl.h" + +/************************** Constant Definitions *****************************/ +/* Bit[0] : 输入延迟功能使能 */ +#define FIOCTRL_DELAY_EN(delay_beg) BIT(delay_beg) +#define FIOCTRL_INPUT_DELAY_OFF 0 + +/* Bit[3:1] : 输入延迟精调档位选择 */ +#define FIOCTRL_DELICATE_DELAY_MASK(delay_beg) GENMASK((delay_beg + 3), (delay_beg + 1)) +#define FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 3), (delay_beg + 1)) +#define FIOCTRL_DELICATE_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 3), (delay_beg + 1)) + +/* Bit[6:4] : 输入延迟粗调档位选择 */ +#define FIOCTRL_ROUGH_DELAY_MASK(delay_beg) GENMASK((delay_beg + 6), (delay_beg + 4)) +#define FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 6), (delay_beg + 4)) +#define FIOCTRL_ROUGH_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 6), (delay_beg + 4)) + +/* Bit[7] : 保留 */ +/* Bit[8] : 输出延迟功能使能 */ + +/* Bit[11:9] : 输出延迟精调档位选择 */ +/* Bit [14:12] : 输出延迟粗调档位选择 */ +/* Bit [15] : 保留 */ + +#define FIOCTRL_FUNC_BEG_OFF(reg_bit) ((reg_bit) + 0) +#define FIOCTRL_FUNC_END_OFF(reg_bit) ((reg_bit) + 1) /* bit[1:0] 复用功能占2个位 */ +#define FIOCTRL_PULL_BEG_OFF(reg_bit) ((reg_bit) + 2) +#define FIOCTRL_PULL_END_OFF(reg_bit) ((reg_bit) + 3) /* bit[3:2] 上下拉功能占2个位 */ + +#define FIOCTRL_DELAY_IN_BEG_OFF(reg_bit) ((reg_bit) + 0) +#define FIOCTRL_DELAY_IN_END_OFF(reg_bit) ((reg_bit) + 7) /* bit[8:1] 输入延时占7个位 */ +#define FIOCTRL_DELAY_OUT_BEG_OFF(reg_bit) ((reg_bit) + 8) +#define FIOCTRL_DELAY_OUT_END_OFF(reg_bit) ((reg_bit) + 15) /* bit[15:9] 输出延时占7个位 */ + +/* 芯片引脚控制寄存器的起止位置 */ +#define FIOCTRL_REG_OFFSET_MIN 0x200 +#define FIOCTRL_REG_OFFSET_MAX 0x22c + +/* 芯片引脚延时寄存器的起止位置 */ +#define FIOCTRL_DELAY_REG_OFFSET_MIN 0x400 +#define FIOCTRL_DELAY_REG_OFFSET_MAX 0x404 + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FIOCTRL_DEBUG_TAG "FIOCTRL" +#define FIOCTRL_ERROR(format, ...) FT_DEBUG_PRINT_E(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_WARN(format, ...) FT_DEBUG_PRINT_W(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_INFO(format, ...) FT_DEBUG_PRINT_I(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) +#define FIOCTRL_DEBUG(format, ...) FT_DEBUG_PRINT_D(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__) + +#define FIOCTRL_ASSERT_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_REG_OFFSET_MAX)), "invalid pin register off @%d", (pin.reg_off)) +#define FIOCTRL_ASSERT_FUNC(func) FASSERT_MSG((func < FPIN_NUM_OF_FUNC), "invalid func as %d", (func)) +#define FIOCTRL_ASSERT_PULL(pull) FASSERT_MSG((pull < FPIN_NUM_OF_PULL), "invalid pull as %d", (pull)) + +#define FIOCTRL_ASSERT_DELAY_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_DELAY_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_DELAY_REG_OFFSET_MAX)), "invalid delay pin register off @%d", (pin.reg_off)) +#define FIOCTRL_ASSERT_DELAY(delay) FASSERT_MSG(((delay) < FPIN_NUM_OF_DELAY), "invalid delay as %d", (delay)); +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ + +/** + * @name: FPinGetFunc + * @msg: 获取IO引脚当前的复用功能 + * @return {FPinFunc} 当前的复用功能 + * @param {FPinIndex} pin IO引脚索引 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +FPinFunc FPinGetFunc(const FPinIndex pin) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 func = GET_REG32_BITS(reg_val, func_end, func_beg); + FIOCTRL_ASSERT_FUNC(func); + + return (FPinFunc)GET_REG32_BITS(reg_val, func_end, func_beg); +} + +/** + * @name: FPinSetFunc + * @msg: 设置IO引脚复用功能 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinFunc} func IO复用功能 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +void FPinSetFunc(const FPinIndex pin, FPinFunc func) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + FIOCTRL_ASSERT_FUNC(func); + + u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit); + u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + reg_val &= ~GENMASK(func_end, func_beg); + reg_val |= SET_REG32_BITS(func, func_end, func_beg); + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinGetPull + * @msg: 获取IO引脚当前的上下拉设置 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值 + */ +FPinPull FPinGetPull(const FPinIndex pin) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 pull = GET_REG32_BITS(reg_val, pull_end, pull_beg); + + FIOCTRL_ASSERT_PULL(pull); + return (FPinPull)pull; +} + +/** + * @name: FPinSetPull + * @msg: 设置IO引脚当前的上下拉 + * @return {*} + * @param {FPinIndex} pin IO引脚索引 + * @param {FPinPull} pull 上下拉设置 + */ +void FPinSetPull(const FPinIndex pin, FPinPull pull) +{ + FIOCTRL_ASSERT_REG_OFF(pin); + FIOCTRL_ASSERT_PULL(pull); + + u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit); + u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + + reg_val &= ~GENMASK(pull_end, pull_beg); + reg_val |= SET_REG32_BITS(pull, pull_end, pull_beg); + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinGetDelay + * @msg: 获取IO引脚当前的延时设置 + * @return {FPinDelay} 当前的延时设置 + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {FPinDelayType} type 精调/粗调延时 + */ +FPinDelay FPinGetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + u8 delay = 0; + const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FPIN_DELAY_FINE_TUNING == type) + { + delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg); /* bit[3:1] delicate delay tune */ + } + else if (FPIN_DELAY_COARSE_TUNING == type) + { + delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg); /* bit[6:4] rough delay adjust */ + } + else + { + FASSERT(0); + } + + FIOCTRL_ASSERT_DELAY(delay); + return (FPinDelay)delay; +} + + +/** + * @name: FPinGetDelayEn + * @msg: 获取IO引脚当前的延时使能标志位 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + */ +boolean FPinGetDelayEn(const FPinIndex pin, FPinDelayDir dir) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + boolean enabled = FALSE; + const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FIOCTRL_DELAY_EN(delay_beg) & reg_val) + { + enabled = TRUE; + } + + return enabled; +} + +/** + * @name: FPinSetDelay + * @msg: 设置IO引脚延时 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {FPinDelayType} type 精调/粗调延时 + * @param {FPinDelay} delay 延时档位设置 0 ~ 8 档可用 + */ +void FPinSetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type, FPinDelay delay) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + FIOCTRL_ASSERT_DELAY(delay); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + if (FPIN_DELAY_FINE_TUNING == type) + { + reg_val &= ~FIOCTRL_DELICATE_DELAY_MASK(delay_beg); + delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg); + } + else if (FPIN_DELAY_COARSE_TUNING == type) + { + reg_val &= ~FIOCTRL_ROUGH_DELAY_MASK(delay_beg); + delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg); + } + else + { + FASSERT(0); + } + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} + +/** + * @name: FPinSetDelayEn + * @msg: 使能/去使能IO引脚延时 + * @return {*} + * @param {FPinIndex} pin IO引脚延时设置索引 + * @param {FPinDelayDir} dir 输入/输出延时 + * @param {boolean} enable TRUE: 使能, FALSE: 去使能 + */ +void FPinSetDelayEn(const FPinIndex pin, FPinDelayDir dir, boolean enable) +{ + FIOCTRL_ASSERT_DELAY_REG_OFF(pin); + u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off); + u32 delay_beg = 0, delay_end = 0; + + if (FPIN_OUTPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off); + } + else if (FPIN_INPUT_DELAY == dir) + { + delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off); + } + else + { + FASSERT(0); + } + + reg_val &= ~FIOCTRL_DELAY_EN(delay_beg); + if (enable) + { + reg_val |= FIOCTRL_DELAY_EN(delay_beg); + } + + FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val); + return; +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.h b/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.h new file mode 100644 index 0000000000..5d0caac525 --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/ft2004/fioctrl.h @@ -0,0 +1,81 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fioctrl.h + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-18 08:25:35 + * Description:  This files is for io-ctrl function definition (io-mux/io-config/io-delay) + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/2/22 init commit + */ + + +#ifndef BOARD_D2000_FIOCTRL_H +#define BOARD_D2000_FIOCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************** Include Files *********************************/ +#include "ftypes.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FIOCTRL_INDEX(offset, func_beg) \ + { \ + /* reg_off */ (offset), \ + /* reg_bit */ (func_beg) \ + } + +/************************** Variable Definitions *****************************/ +#define FIOCTRL_CRU_CLK_OBV_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 24) +#define FIOCTRL_SPI0_CSN0_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 16) +#define FIOCTRL_SPI0_SCK_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 12) +#define FIOCTRL_SPI0_SO_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 8) +#define FIOCTRL_SPI0_SI_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 4) + +#define FIOCTRL_TJTAG_TDI_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 24) /* can0-tx: func 1 */ +#define FIOCTRL_SWDITMS_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 12) /* can0-rx: func 1 */ + +#define FIOCTRL_NTRST_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 20) /* can1-tx: func 1 */ +#define FIOCTRL_SWDO_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 8) /* can1-rx: func 1 */ + +#define FIOCTRL_I2C0_SCL_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 24) /* i2c0-scl: func 0 */ +#define FIOCTRL_I2C0_SDA_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 20) /* i2c0-sda: func 0 */ +#define FIOCTRL_ALL_PLL_LOCK_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 28) /* i2c1-scl: func 2 */ +#define FIOCTRL_CRU_CLK_OBV_PAD (FPinIndex)FIOCTRL_INDEX(0x200, 24) /* i2c1-sda: func 2 */ +#define FIOCTRL_SWDO_SWJ_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 8) /* i2c2-scl: func 2 */ +#define FIOCTRL_TDO_SWJ_IN_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 4) /* i2c2-sda: func 2 */ +#define FIOCTRL_HDT_MB_DONE_STATE_PAD (FPinIndex)FIOCTRL_INDEX(0x204, 0) /* i2c3-scl: func 2 */ +#define FIOCTRL_HDT_MB_FAIL_STATE_PAD (FPinIndex)FIOCTRL_INDEX(0x208, 28) /* i2c3-sda: func 2 */ + +#define FIOCTRL_UART_2_RXD_PAD (FPinIndex)FIOCTRL_INDEX(0x210, 0) /* spi1_csn0: func 1 */ +#define FIOCTRL_UART_2_TXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 28) /* spi1_sck: func 1 */ +#define FIOCTRL_UART_3_RXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 24) /* spi1_so: func 1 */ +#define FIOCTRL_UART_3_TXD_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 20) /* spi1_si: func 1 */ +#define FIOCTRL_QSPI_CSN2_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 8) /* spi1_csn1: func 1 */ +#define FIOCTRL_QSPI_CSN3_PAD (FPinIndex)FIOCTRL_INDEX(0x214, 4) /* spi1_csn2: func 1 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/phytium/libraries/standalone/board/ft2004/fparameters.h b/bsp/phytium/libraries/standalone/board/ft2004/fparameters.h new file mode 100644 index 0000000000..61a1943a5b --- /dev/null +++ b/bsp/phytium/libraries/standalone/board/ft2004/fparameters.h @@ -0,0 +1,327 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fparameters.h + * Date: 2022-02-10 14:53:42 + * LastEditTime: 2022-02-17 18:01:11 + * Description:  This file is for + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + */ + +#ifndef BSP_ARCH_ARMV8_AARCH64_PLATFORM_FT2004_H +#define BSP_ARCH_ARMV8_AARCH64_PLATFORM_FT2004_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__ASSEMBLER__) +#include "ftypes.h" +#endif + +#define CORE0_AFF 0x0 +#define CORE1_AFF 0x1 +#define CORE2_AFF 0x100 +#define CORE3_AFF 0x101 + + +/* cache */ +#define CACHE_LINE_ADDR_MASK 0x3F +#define CACHE_LINE 64U + + +/* Device register address */ +#define FDEV_BASE_ADDR 0x28000000 +#define FDEV_END_ADDR 0x2FFFFFFF + +/* PCI */ + +#define FPCIE_NUM 1 +#define FPCIE0_ID 0 +#define FPCIE0_MISC_IRQ_NUM 59 + +#define FPCIE_CFG_MAX_NUM_OF_BUS 256 +#define FPCIE_CFG_MAX_NUM_OF_DEV 32 +#define FPCIE_CFG_MAX_NUM_OF_FUN 8 + +#define FPCI_CONFIG_BASE_ADDR 0x40000000 +#define FPCI_CONFIG_REG_LENGTH 0x10000000 + +#define FPCI_IO_CONFIG_BASE_ADDR 0x50000000 +#define FPCI_IO_CONFIG_REG_LENGTH 0x08000000 + +#define FPCI_MEM32_BASE_ADDR 0x58000000 +#define FPCI_MEM32_REG_LENGTH 0x27ffffff + +#define FPCI_MEM64_BASE_ADDR 0x1000000000 +#define FPCI_MEM64_REG_LENGTH 0x1000000000 + +#define FPCI_EU0_C0_CONTROL_BASE_ADDR 0x29000000 +#define FPCI_EU0_C1_CONTROL_BASE_ADDR 0x29010000 +#define FPCI_EU0_C2_CONTROL_BASE_ADDR 0x29020000 +#define FPCI_EU1_C0_CONTROL_BASE_ADDR 0x29030000 +#define FPCI_EU1_C1_CONTROL_BASE_ADDR 0x29040000 +#define FPCI_EU1_C2_CONTROL_BASE_ADDR 0x29050000 + +#define FPCI_EU0_CONFIG_BASE_ADDR 0x29100000 +#define FPCI_EU1_CONFIG_BASE_ADDR 0x29101000 + +#define FPCI_INTA_IRQ_NUM 60 +#define FPCI_INTB_IRQ_NUM 61 +#define FPCI_INTC_IRQ_NUM 62 +#define FPCI_INTD_IRQ_NUM 63 + +#define FPCI_NEED_SKIP 1 + +/* platform ahci host */ +#define PLAT_AHCI_HOST_MAX_COUNT 5 +#define AHCI_BASE_0 0 +#define AHCI_BASE_1 0 +#define AHCI_BASE_2 0 +#define AHCI_BASE_3 0 +#define AHCI_BASE_4 0 + +#define AHCI_IRQ_0 0 +#define AHCI_IRQ_1 0 +#define AHCI_IRQ_2 0 +#define AHCI_IRQ_3 0 +#define AHCI_IRQ_4 0 + +// timer +#define GENERIC_TIMER_NS_IRQ_NUM 30 +#define COUNTS_PER_SECOND GENERIC_TIMER_CLK_FREQ + +// UART + +#define FUART_NUM 4 +#define FUART_REG_LENGTH 0x18000 + +#define FUART0_ID 0 +#define FUART0_IRQ_NUM 38 +#define FUART0_BASE_ADDR 0x28000000 +#define FUART0_CLK_FREQ_HZ 48000000 + +#define FUART1_ID 1 +#define FUART1_IRQ_NUM 39 +#define FUART1_BASE_ADDR 0x28001000 +#define FUART1_CLK_FREQ_HZ 48000000 + +#define FUART2_ID 2 +#define FUART2_IRQ_NUM 40 +#define FUART2_BASE_ADDR 0x28002000 +#define FUART2_CLK_FREQ_HZ 48000000 + +#define FUART3_BASE_ADDR 0x28003000 +#define FUART3_ID 3 +#define FUART3_IRQ_NUM 41 +#define FUART3_CLK_FREQ_HZ 48000000 + +#define FT_STDOUT_BASE_ADDRESS FUART1_BASE_ADDR +#define FT_STDIN_BASE_ADDRESS FUART1_BASE_ADDR + +/****** GIC v3 *****/ +#define FT_GICV3_INSTANCES_NUM 1U +#define GICV3_REG_LENGTH 0x00009000 + +/* + * The maximum priority value that can be used in the GIC. + */ +#define GICV3_MAX_INTR_PRIO_VAL 240U +#define GICV3_INTR_PRIO_MASK 0x000000f0U +#define ARM_GIC_IPI_COUNT 16 /* MPCore IPI count */ +#define SGI_INT_MAX 16 +#define SPI_START_INT_NUM 32 /* SPI start at ID32 */ +#define PPI_START_INT_NUM 16 /* PPI start at ID16 */ +#define GIC_INT_MAX_NUM 1020 /* GIC max interrupts count */ +#define GICV3_BASE_ADDR 0x29900000U +#define GICV3_DISTRIBUTOR_BASE_ADDR (GICV3_BASE_ADDR + 0) +#define GICV3_RD_BASE_ADDR (GICV3_BASE_ADDR + 0x80000U) +#define GICV3_RD_OFFSET (2U << 16) +#define FT_GICV3_VECTORTABLE_NUM GIC_INT_MAX_NUM + +/* GPIO */ +#define FGPIO0_BASE_ADDR 0x28004000 +#define FGPIO1_BASE_ADDR 0x28005000 + +#define FGPIO0_ID 0 +#define FGPIO1_ID 1 +#define FGPIO_NUM 2 + +#define FGPIO0_IRQ_NUM 42 /* gpio0 irq number */ +#define FGPIO1_IRQ_NUM 43 /* gpio1 irq number */ + +/* SPI */ +#define FSPI0_BASE_ADDR 0x2800c000 +#define FSPI1_BASE_ADDR 0x28013000 +#define FSPI0_ID 0 +#define FSPI1_ID 1 +#define FSPI_CLK_FREQ_HZ 48000000 +#define FSPI_NUM 2 +#define FSPI0_IRQ_NUM 50 +#define FSPI1_IRQ_NUM 51 + +/* QSPI */ +/* QSPI */ +#if !defined(__ASSEMBLER__) +typedef enum +{ + FQSPI0_ID = 0, + + FQSPI_NUM +} FQspiInstance; + +/* FQSPI cs 0_3, chip number */ +enum +{ + FQSPI_CS_0 = 0, + FQSPI_CS_1 = 1, + FQSPI_CS_2 = 2, + FQSPI_CS_3 = 3, + FQSPI_CS_NUM +}; +#endif + +#define FQSPI_BASE_ADDR 0x28014000 +#define FQSPI_MEM_START_ADDR 0x0 +#define FQSPI_MEM_END_ADDR 0x1FFFFFFF + +/* IOCTRL */ +#define FIOCTRL_REG_BASE_ADDR 0x28180000 + +// Gic +#define ARM_GIC_NR_IRQS 1024 +#define ARM_GIC_IRQ_START 0 +#define FGIC_NUM 1 + +/* can */ +#if !defined(__ASSEMBLER__) +enum +{ + FCAN0_ID = 0, + FCAN1_ID = 1, + FCAN2_ID = 2, + + FCAN_NUM +}; +#endif + +#define FCAN_CLK_FREQ_HZ 600000000 + +#define FCAN0_BASE_ADDR 0x28207000 +#define FCAN1_BASE_ADDR 0x28207400 +#define FCAN2_BASE_ADDR 0x28207800 +#define FCAN0_IRQ_NUM 119 +#define FCAN1_IRQ_NUM 123 +#define FCAN2_IRQNUM 124 + +/* I2C */ +#if !defined(__ASSEMBLER__) +enum +{ + FI2C0_ID = 0, + FI2C1_ID = 1, + FI2C2_ID, + FI2C3_ID, + + FI2C_NUM +}; +#endif + +#define FI2C0_BASE_ADDR 0x28006000 +#define FI2C1_BASE_ADDR 0x28007000 +#define FI2C2_BASE_ADDR 0x28008000 +#define FI2C3_BASE_ADDR 0x28009000 + +#define FI2C0_IRQ_NUM 44 +#define FI2C1_IRQ_NUM 45 +#define FI2C2_IRQ_NUM 46 +#define FI2C3_IRQ_NUM 47 + +#define FI2C_CLK_FREQ_HZ 48000000 /* 48MHz */ + +/* WDT */ +#if !defined(__ASSEMBLER__) +enum +{ + FWDT0_ID = 0, + FWDT1_ID = 1, + + FWDT_NUM +} ; +#endif + +#define FWDT0_REFRESH_BASE_ADDR 0x2800a000 +#define FWDT1_REFRESH_BASE_ADDR 0x28016000 + +#define FWDT_CONTROL_BASE_ADDR(x) ((x)+0x1000) + +#define FWDT0_IRQ_NUM 48 +#define FWDT1_IRQ_NUM 49 + +#define FWDT_CLK_FREQ_HZ 48000000 /* 48MHz */ + +/* SDCI */ +#if !defined(__ASSEMBLER__) +enum +{ + FSDMMC0_ID = 0, + FSDMMC_NUM +}; +#endif + +#define FSDMMC0_BASE_ADDR 0x28207C00 + +#define FSDMMC0_DMA_IRQ_NUM 52 +#define FSDMMC0_CMD_IRQ_NUM 53 +#define FSDMMC0_ERR_IRQ_NUM 54 + +#define FSDMMC_CLK_FREQ_HZ 600000000 /* 600 MHz */ +#define SDCI_SEN_DEBNCE 10000000 /* 10 MHz */ +#define SDCI_CMD_TIMEOUT 10000000 /* 1s */ +#define SDCI_DATA_TIMEOUT 40000000 /* 4S */ + +/* GMAC */ +#if !defined(__ASSEMBLER__) +enum +{ + FGMAC0_ID = 0, + FGMAC1_ID, + + FGMAC_NUM +}; +#endif +#define FGMAC_PUB_REG_BASE_ADDR 0x2820B000 /* 公共寄存器基地址 */ + +#define FGMAC0_BASE_ADDR 0x2820C000 +#define FGMAC1_BASE_ADDR 0x28210000 + +#define FGMAC0_IRQ_NUM 81 +#define FGMAC1_IRQ_NUM 82 + +#define FGMAC_DMA_MIN_ALIGN 128 +#define FGMAC_MAX_PACKET_SIZE 1600 + +/*RTC*/ +#define RTC_CONTROL_BASE 0x2800D000 + +#define FT_CPUS_NR CORE_NUM + +#ifdef __cplusplus +} +#endif + +#endif // ! \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/common/Kconfig b/bsp/phytium/libraries/standalone/common/Kconfig index aa2fd1c471..221bbbaca2 100644 --- a/bsp/phytium/libraries/standalone/common/Kconfig +++ b/bsp/phytium/libraries/standalone/common/Kconfig @@ -1,6 +1,5 @@ - choice DEBUG_LOG_LEVEL prompt "Debug Log Level" default LOG_ERROR @@ -31,7 +30,7 @@ config USE_DEFAULT_INTERRUPT_CONFIG bool prompt "Use default interrupt configuration" default y - help + help "If this option is not selected, core0 is used as the main core by default and all interrupt driver modules are initialized. Non-0 core initializes only the necessary interrupt driver modules. If this option is selected, the developer needs to initiate each module independently " if USE_DEFAULT_INTERRUPT_CONFIG choice INTERRUPT_ROLE_SELECT @@ -41,8 +40,8 @@ config USE_DEFAULT_INTERRUPT_CONFIG "Select Interrupt role" config INTERRUPT_ROLE_MASTER - bool "use master role" - + bool "use master role" + config INTERRUPT_ROLE_SLAVE bool "use slave role" @@ -55,10 +54,16 @@ config LOG_EXTRA_INFO help Print debug information with source file name and source code line num. +config LOG_DISPALY_CORE_NUM + bool "Debug Display with Core" + default n + help + To display CPU core information during debugging + config BOOTUP_DEBUG_PRINTS bool prompt "Bootup debug" default n help Enable Bootup debug printing - + diff --git a/bsp/phytium/libraries/standalone/common/fassert.c b/bsp/phytium/libraries/standalone/common/fassert.c index ec1ade974b..ad23aeee26 100644 --- a/bsp/phytium/libraries/standalone/common/fassert.c +++ b/bsp/phytium/libraries/standalone/common/fassert.c @@ -11,16 +11,16 @@ * See the Phytium Public License for more details. * * - * FilePath: ft_assert.c + * FilePath: fassert.c * Date: 2021-04-07 09:53:07 * LastEditTime: 2022-02-17 18:04:28 - * Description:  This files is for assertion implmentation + * Description:  This file is for assertion implmentation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021.4 init commit - * 1.1 zhugengyu 2022.3 re-define assert macro + * 1.0 huanghe 2021/4/5 init commit + * 1.1 zhugengyu 2022/3/7 re-define assert macro */ /***************************** Include Files *********************************/ @@ -92,7 +92,9 @@ static void FAssertCallback(const char *file, s32 line, int ret) void FAssertSetCB(FAssertCB cb) { if (NULL != cb) + { assert_info.cb = cb; + } } /** diff --git a/bsp/phytium/libraries/standalone/common/fassert.h b/bsp/phytium/libraries/standalone/common/fassert.h index 9bb44362ff..47e3a44147 100644 --- a/bsp/phytium/libraries/standalone/common/fassert.h +++ b/bsp/phytium/libraries/standalone/common/fassert.h @@ -14,29 +14,27 @@ * FilePath: fassert.h * Date: 2021-04-07 09:53:07 * LastEditTime: 2022-02-17 18:04:35 - * Description:  This files is for assertion defintion + * Description:  This file is for assertion defintion. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021.4 init commit - * 1.1 zhugengyu 2022.3 re-define assert macro + * 1.0 huanghe 2021/4/5 init commit + * 1.1 zhugengyu 2022/3/7 re-define assert macro */ -#ifndef FT_ASSERT_H -#define FT_ASSERT_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FASSERT_H +#define FASSERT_H /***************************** Include Files *********************************/ #include "fprintk.h" #include "ferror_code.h" #include "ftypes.h" -/************************** Constant Definitions *****************************/ +#ifdef __cplusplus +extern "C" +{ +#endif /**************************** Type Definitions *******************************/ typedef enum diff --git a/bsp/phytium/libraries/standalone/common/fdebug.c b/bsp/phytium/libraries/standalone/common/fdebug.c index 2a6d906e59..60a5f70e77 100644 --- a/bsp/phytium/libraries/standalone/common/fdebug.c +++ b/bsp/phytium/libraries/standalone/common/fdebug.c @@ -11,18 +11,19 @@ * See the Phytium Public License for more details. * * - * FilePath: ft_debug.c + * FilePath: fdebug.c * Date: 2021-04-25 16:44:23 * LastEditTime: 2022-02-17 18:04:50 - * Description:  This files is for + * Description:  This file is for providing debug functions. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/27 rename file name */ #include "fdebug.h" -#include "fprintf.h" +#include "fprintk.h" #include "stdio.h" #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') @@ -33,19 +34,25 @@ void FtDumpHexByte(const u8 *ptr, u32 buflen) for (i = 0; i < buflen; i += 16) { - printf("%p: ", ptr + i); + f_printk("%p: ", ptr + i); for (j = 0; j < 16; j++) if (i + j < buflen) - printf("%02X ", buf[i + j]); + { + f_printk("%02X ", buf[i + j]); + } else - printf(" "); - printf(" "); + { + f_printk(" "); + } + f_printk(" "); for (j = 0; j < 16; j++) if (i + j < buflen) - printf("%c", (char)(__is_print(buf[i + j]) ? buf[i + j] : '.')); - printf("\r\n"); + { + f_printk("%c", (char)(__is_print(buf[i + j]) ? buf[i + j] : '.')); + } + f_printk("\r\n"); } } @@ -56,19 +63,25 @@ void FtDumpHexByteDebug(const u8 *ptr, u32 buflen) for (i = 0; i < buflen; i += 16) { - f_printf("%x: ", ptr + i); + f_printk("%x: ", ptr + i); for (j = 0; j < 16; j++) if (i + j < buflen) - f_printf("%x ", buf[i + j]); + { + f_printk("%x ", buf[i + j]); + } else - f_printf(" "); - f_printf(" "); + { + f_printk(" "); + } + f_printk(" "); for (j = 0; j < 16; j++) if (i + j < buflen) - f_printf("%c", (char)(__is_print(buf[i + j]) ? buf[i + j] : '.')); - f_printf("\r\n"); + { + f_printk("%c", (char)(__is_print(buf[i + j]) ? buf[i + j] : '.')); + } + f_printk("\r\n"); } } @@ -81,26 +94,28 @@ void FtDumpHexWord(const u32 *ptr, u32 buflen) buflen = buflen / 4; for (i = 0; i < buflen; i += 4) { - printf("%p: ", ptr + i); + f_printk("%p: ", ptr + i); for (j = 0; j < 4; j++) { if (i + j < buflen) { - printf("%lx ", buf[i + j]); + f_printk("%lx ", buf[i + j]); } else { - printf(" "); + f_printk(" "); } } - printf(" "); + f_printk(" "); for (j = 0; j < 16; j++) if (i + j < buflen) - printf("%c", (char)(__is_print(char_data[i + j]) ? char_data[i + j] : '.')); + { + f_printk("%c", (char)(__is_print(char_data[i + j]) ? char_data[i + j] : '.')); + } - printf("\r\n"); + f_printk("\r\n"); } } diff --git a/bsp/phytium/libraries/standalone/common/fdebug.h b/bsp/phytium/libraries/standalone/common/fdebug.h index 84f283b75e..63d8a218fc 100644 --- a/bsp/phytium/libraries/standalone/common/fdebug.h +++ b/bsp/phytium/libraries/standalone/common/fdebug.h @@ -14,18 +14,34 @@ * FilePath: fdebug.h * Date: 2021-04-07 09:53:07 * LastEditTime: 2022-02-17 18:04:58 - * Description:  This files is for debug functions + * Description:  This file is for showing debug api. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/27 rename file name */ -#ifndef BSP_COMMON_FT_DEBUG_H -#define BSP_COMMON_FT_DEBUG_H +#ifndef FDEBUG_H +#define FDEBUG_H + #include #include "sdkconfig.h" #include "ftypes.h" +#include "fprintk.h" +#ifdef CONFIG_USE_AMP +#include "fsmp.h" +#endif + +#if defined(CONFIG_USE_AMP) +#include "fcpu_info.h" +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif typedef enum { @@ -76,7 +92,26 @@ typedef enum #define LOG_FORMAT(letter, format) LOG_COLOR_##letter " %s: " format LOG_RESET_COLOR "\r\n" -#define PORT_KPRINTF printf +#define PORT_KPRINTF f_printk + +#if defined(CONFIG_LOG_DISPALY_CORE_NUM) + #define DISPALY_CORE_NUM() \ + do {u32 cpu_id; \ + GetCpuId(&cpu_id); \ + PORT_KPRINTF("cpu%d:", cpu_id); } while(0) +#else +#define DISPALY_CORE_NUM() +#endif + + +#ifdef CONFIG_USE_AMP +#define LOG_SPIN_LOCK() SpinLock(); +#define LOG_SPIN_UNLOCK() SpinUnlock() ; +#else +#define LOG_SPIN_LOCK() +#define LOG_SPIN_UNLOCK() +#endif + #ifndef CONFIG_LOG_EXTRA_INFO #define LOG_EARLY_IMPL(tag, format, log_level, log_tag_letter, ...) \ @@ -84,7 +119,10 @@ typedef enum { \ if (LOG_LOCAL_LEVEL < log_level) \ break; \ + LOG_SPIN_LOCK(); \ + DISPALY_CORE_NUM(); \ PORT_KPRINTF(LOG_FORMAT(log_tag_letter, format), tag, ##__VA_ARGS__); \ + LOG_SPIN_UNLOCK(); \ } while (0) #else #include @@ -95,6 +133,7 @@ typedef enum { \ if (LOG_LOCAL_LEVEL < log_level) \ break; \ + DISPALY_CORE_NUM() \ PORT_KPRINTF(LOG_FORMAT(log_tag_letter, format" @%s:%d"), tag, ##__VA_ARGS__, __FILENAME__, __LINE__); \ } while (0) #endif @@ -124,4 +163,9 @@ typedef enum void FtDumpHexWord(const u32 *ptr, u32 buflen); void FtDumpHexByte(const u8 *ptr, u32 buflen); + +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/bsp/phytium/libraries/standalone/common/felf.c b/bsp/phytium/libraries/standalone/common/felf.c new file mode 100644 index 0000000000..93b423c425 --- /dev/null +++ b/bsp/phytium/libraries/standalone/common/felf.c @@ -0,0 +1,987 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: felf.c + * Date: 2021-08-31 11:16:59 + * LastEditTime: 2022-02-17 18:05:16 + * Description:  This file is for providing elf functions. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/27 rename file name + */ + +#include +#include "fkernel.h" +#include "felf.h" +#include "fcache.h" +#include "fdebug.h" +#include "fprintk.h" +/* This version doesn't work for 64-bit ABIs - Erik */ + +/* These typedefs need to be handled better */ +typedef u32 Elf32_Addr; /* Unsigned program address */ +typedef u32 Elf32_Off; /* Unsigned file offset */ +typedef s32 Elf32_Sword; /* Signed large integer */ +typedef u32 Elf32_Word; /* Unsigned large integer */ +typedef u16 Elf32_Half; /* Unsigned medium integer */ + +/* 64-bit ELF base types */ +typedef u64 Elf64_Addr; +typedef u16 Elf64_Half; +typedef s16 Elf64_SHalf; +typedef u64 Elf64_Off; +typedef s32 Elf64_Sword; +typedef u32 Elf64_Word; +typedef u64 Elf64_Xword; +typedef s64 Elf64_Sxword; + +/* e_ident[] identification indexes */ +#define EI_MAG0 0 /* file ID */ +#define EI_MAG1 1 /* file ID */ +#define EI_MAG2 2 /* file ID */ +#define EI_MAG3 3 /* file ID */ +#define EI_CLASS 4 /* file class */ +#define EI_DATA 5 /* data encoding */ +#define EI_VERSION 6 /* ELF header version */ +#define EI_OSABI 7 /* OS/ABI specific ELF extensions */ +#define EI_ABIVERSION 8 /* ABI target version */ +#define EI_PAD 9 /* start of pad bytes */ +#define EI_NIDENT 16 /* Size of e_ident[] */ + +/* ELF Header */ +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ + Elf32_Half e_type; /* object file type */ + Elf32_Half e_machine; /* machine */ + Elf32_Word e_version; /* object file version */ + Elf32_Addr e_entry; /* virtual entry point */ + Elf32_Off e_phoff; /* program header table offset */ + Elf32_Off e_shoff; /* section header table offset */ + Elf32_Word e_flags; /* processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size */ + Elf32_Half e_phentsize; /* program header entry size */ + Elf32_Half e_phnum; /* number of program header entries */ + Elf32_Half e_shentsize; /* section header entry size */ + Elf32_Half e_shnum; /* number of section header entries */ + Elf32_Half e_shstrndx; /* section header table's "section + header string table" entry offset */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ + Elf64_Half e_type; /* object file type */ + Elf64_Half e_machine; /* machine */ + Elf64_Word e_version; /* object file version */ + Elf64_Addr e_entry; /* virtual entry point */ + Elf64_Off e_phoff; /* program header table offset */ + Elf64_Off e_shoff; /* section header table offset */ + Elf64_Word e_flags; /* processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size */ + Elf64_Half e_phentsize; /* program header entry size */ + Elf64_Half e_phnum; /* number of program header entries */ + Elf64_Half e_shentsize; /* section header entry size */ + Elf64_Half e_shnum; /* number of section header entries */ + Elf64_Half e_shstrndx; /* section header table's "section + header string table" entry offset */ +} Elf64_Ehdr; + +/* Section Header */ +typedef struct +{ + Elf32_Word sh_name; /* name - index into section header + string table section */ + Elf32_Word sh_type; /* type */ + Elf32_Word sh_flags; /* flags */ + Elf32_Addr sh_addr; /* address */ + Elf32_Off sh_offset; /* file offset */ + Elf32_Word sh_size; /* section size */ + Elf32_Word sh_link; /* section header table index link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* address alignment */ + Elf32_Word sh_entsize; /* section entry size */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* name - index into section header + string table section */ + Elf64_Word sh_type; /* type */ + Elf64_Xword sh_flags; /* flags */ + Elf64_Addr sh_addr; /* address */ + Elf64_Off sh_offset; /* file offset */ + Elf64_Xword sh_size; /* section size */ + Elf64_Word sh_link; /* section header table index link */ + Elf64_Word sh_info; /* extra information */ + Elf64_Xword sh_addralign; /* address alignment */ + Elf64_Xword sh_entsize; /* section entry size */ +} Elf64_Shdr; + +/* Symbol Table Entry */ +typedef struct +{ + Elf32_Word st_name; /* name - index into string table */ + Elf32_Addr st_value; /* symbol value */ + Elf32_Word st_size; /* symbol size */ + unsigned char st_info; /* type and binding */ + unsigned char st_other; /* 0 - no defined meaning */ + Elf32_Half st_shndx; /* section header index */ +} Elf32_Sym; + +/* Relocation entry with implicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ +} Elf32_Rel; + +/* Relocation entry with explicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ + Elf32_Sword r_addend; +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Location at which to apply the action */ + Elf64_Xword r_info; /* index and type of relocation */ +} Elf64_Rel; + +typedef struct +{ + Elf64_Addr r_offset; /* Location at which to apply the action */ + Elf64_Xword r_info; /* index and type of relocation */ + Elf64_Sxword r_addend; /* Constant addend used to compute value */ +} Elf64_Rela; + +/* Program Header */ +typedef struct +{ + Elf32_Word p_type; /* segment type */ + Elf32_Off p_offset; /* segment offset */ + Elf32_Addr p_vaddr; /* virtual address of segment */ + Elf32_Addr p_paddr; /* physical address of segment */ + Elf32_Word p_filesz; /* number of bytes in file for seg */ + Elf32_Word p_memsz; /* number of bytes in mem. for seg */ + Elf32_Word p_flags; /* flags */ + Elf32_Word p_align; /* memory alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* segment type */ + Elf64_Word p_flags; /* flags */ + Elf64_Off p_offset; /* segment offset */ + Elf64_Addr p_vaddr; /* virtual address of segment */ + Elf64_Addr p_paddr; /* physical address of segment */ + Elf64_Xword p_filesz; /* number of bytes in file for seg */ + Elf64_Xword p_memsz; /* number of bytes in mem. for seg */ + Elf64_Xword p_align; /* memory alignment */ +} Elf64_Phdr; + +/* Dynamic structure */ +typedef struct +{ + Elf32_Sword d_tag; /* controls meaning of d_val */ + union + { + Elf32_Word d_val; /* Multiple meanings - see d_tag */ + Elf32_Addr d_ptr; /* program virtual address */ + } d_un; +} Elf32_Dyn; + +extern Elf32_Dyn _DYNAMIC[]; + +typedef struct +{ + Elf64_Sxword d_tag; /* entry tag value */ + union + { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; + +/* e_ident[] magic number */ +#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +#define ELFMAG "\177ELF" /* magic */ +#define SELFMAG 4 /* size of magic */ + +/* e_ident[] file class */ +#define ELFCLASSNONE 0 /* invalid */ +#define ELFCLASS32 1 /* 32-bit objs */ +#define ELFCLASS64 2 /* 64-bit objs */ +#define ELFCLASSNUM 3 /* number of classes */ + +/* e_ident[] data encoding */ +#define ELFDATANONE 0 /* invalid */ +#define ELFDATA2LSB 1 /* Little-Endian */ +#define ELFDATA2MSB 2 /* Big-Endian */ +#define ELFDATANUM 3 /* number of data encode defines */ + +/* e_ident[] OS/ABI specific ELF extensions */ +#define ELFOSABI_NONE 0 /* No extension specified */ +#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* Linux */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +/* 64-255 Architecture-specific value range */ + +/* e_ident[] ABI Version */ +#define ELFABIVERSION 0 + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* e_type */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* relocatable file */ +#define ET_EXEC 2 /* executable file */ +#define ET_DYN 3 /* shared object file */ +#define ET_CORE 4 /* core file */ +#define ET_NUM 5 /* number of types */ +#define ET_LOOS 0xfe00 /* reserved range for operating */ +#define ET_HIOS 0xfeff /* system specific e_type */ +#define ET_LOPROC 0xff00 /* reserved range for processor */ +#define ET_HIPROC 0xffff /* specific e_type */ + +/* e_machine */ +#define EM_NONE 0 /* No Machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola 68000 */ +#define EM_88K 5 /* Motorola 88000 */ +#if 0 + #define EM_486 6 /* RESERVED - was Intel 80486 */ +#endif +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ +#define EM_S370 9 /* IBM System/370 Processor */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#if 0 +#define EM_SPARC64 11 /* RESERVED - was SPARC v9 \ +64-bit unoffical */ +#endif +/* RESERVED 11-14 for future use */ +#define EM_PARISC 15 /* HPPA */ +/* RESERVED 16 for future use */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM System/390 Processor */ +/* RESERVED 23-35 for future use */ +#define EM_V800 36 /* NEC V800 */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* Advanced Risc Machines ARM */ +#define EM_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC Version 9 */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 */ +#define EM_PDSP 63 /* Sony DSP Processor */ +/* RESERVED 64,65 for future use */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CHRIS 76 /* Axis Communications embedded proc. */ +#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */ +#define EM_HUANY 81 /* Harvard University mach-indep objs */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi DV10V */ +#define EM_D30V 86 /* Mitsubishi DV30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10200 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_NUM 92 /* number of machine types */ + +/* Version */ +#define EV_NONE 0 /* Invalid */ +#define EV_CURRENT 1 /* Current */ +#define EV_NUM 2 /* number of versions */ + +/* Special Section Indexes */ +#define SHN_UNDEF 0 /* undefined */ +#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +#define SHN_LOPROC 0xff00 /* reserved range for processor */ +#define SHN_HIPROC 0xff1f /* specific section indexes */ +#define SHN_LOOS 0xff20 /* reserved range for operating */ +#define SHN_HIOS 0xff3f /* specific semantics */ +#define SHN_ABS 0xfff1 /* absolute value */ +#define SHN_COMMON 0xfff2 /* common symbol */ +#define SHN_XINDEX 0xffff /* Index is an extra table */ +#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* number of section types */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_HIOS 0x6fffffff /* End OS-specific */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Section names */ +#define ELF_BSS ".bss" /* uninitialized data */ +#define ELF_COMMENT ".comment" /* version control information */ +#define ELF_DATA ".data" /* initialized data */ +#define ELF_DATA1 ".data1" /* initialized data */ +#define ELF_DEBUG ".debug" /* debug */ +#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +#define ELF_FINI ".fini" /* termination code */ +#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */ +#define ELF_GOT ".got" /* global offset table */ +#define ELF_HASH ".hash" /* symbol hash table */ +#define ELF_INIT ".init" /* initialization code */ +#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */ +#define ELF_INTERP ".interp" /* Pathname of program interpreter */ +#define ELF_LINE ".line" /* Symbolic line numnber information */ +#define ELF_NOTE ".note" /* Contains note section */ +#define ELF_PLT ".plt" /* Procedure linkage table */ +#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */ +#define ELF_REL_DATA ".rel.data" /* relocation data */ +#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +#define ELF_REL_TEXT ".rel.text" /* relocation code */ +#define ELF_RODATA ".rodata" /* read-only data */ +#define ELF_RODATA1 ".rodata1" /* read-only data */ +#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +#define ELF_STRTAB ".strtab" /* string table */ +#define ELF_SYMTAB ".symtab" /* symbol table */ +#define ELF_SYMTAB_SHNDX ".symtab_shndx" /* symbol table section index */ +#define ELF_TBSS ".tbss" /* thread local uninit data */ +#define ELF_TDATA ".tdata" /* thread local init data */ +#define ELF_TDATA1 ".tdata1" /* thread local init data */ +#define ELF_TEXT ".text" /* code */ + +/* Section Attribute Flags - sh_flags */ +#define SHF_WRITE 0x1 /* Writable */ +#define SHF_ALLOC 0x2 /* occupies memory */ +#define SHF_EXECINSTR 0x4 /* executable */ +#define SHF_MERGE 0x10 /* Might be merged */ +#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */ +#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */ +#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/ +#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */ +#define SHF_GROUP 0x200 /* Member of section group */ +#define SHF_TLS 0x400 /* Thread local storage */ +#define SHF_MASKOS 0x0ff00000 /* OS specific */ +#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ +/* specific section attributes */ + +/* Section Group Flags */ +#define GRP_COMDAT 0x1 /* COMDAT group */ +#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */ +#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */ + +/* Symbol table index */ +#define STN_UNDEF 0 /* undefined */ + +/* Extract symbol info - st_info */ +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int)x) & 0xf) +#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t)&0xf)) +#define ELF32_ST_VISIBILITY(x) ((x)&0x3) + +/* Symbol Binding - ELF32_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_NUM 3 /* number of symbol bindings */ +#define STB_LOOS 10 /* reserved range for operating */ +#define STB_HIOS 12 /* system specific symbol bindings */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +/* Symbol type - ELF32_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* not specified */ +#define STT_OBJECT 1 /* data object */ +#define STT_FUNC 2 /* function */ +#define STT_SECTION 3 /* section */ +#define STT_FILE 4 /* file */ +#define STT_NUM 5 /* number of symbol types */ +#define STT_TLS 6 /* Thread local storage symbol */ +#define STT_LOOS 10 /* reserved range for operating */ +#define STT_HIOS 12 /* system specific symbol types */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0 /* Normal visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Symbol unavailable in other mods */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + +/* Extract relocation info - r_info */ +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) + +/* Segment types - p_type */ +#define PT_NULL 0 /* unused */ +#define PT_LOAD 1 /* loadable segment */ +#define PT_DYNAMIC 2 /* dynamic linking section */ +#define PT_INTERP 3 /* the RTLD */ +#define PT_NOTE 4 /* auxiliary information */ +#define PT_SHLIB 5 /* reserved - purpose undefined */ +#define PT_PHDR 6 /* program header */ +#define PT_TLS 7 /* Thread local storage template */ +#define PT_NUM 8 /* Number of segment types */ +#define PT_LOOS 0x60000000 /* reserved range for operating */ +#define PT_HIOS 0x6fffffff /* system specific segment types */ +#define PT_LOPROC 0x70000000 /* reserved range for processor */ +#define PT_HIPROC 0x7fffffff /* specific segment types */ + +/* Segment flags - p_flags */ +#define PF_X 0x1 /* Executable */ +#define PF_W 0x2 /* Writable */ +#define PF_R 0x4 /* Readable */ +#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */ +#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ +/* specific segment flags */ + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i)&0xffffffff) + +/* Dynamic Array Tags - d_tag */ +#define DT_NULL 0 /* marks end of _DYNAMIC array */ +#define DT_NEEDED 1 /* string table offset of needed lib */ +#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +#define DT_PLTGOT 3 /* address PLT/GOT */ +#define DT_HASH 4 /* address of symbol hash table */ +#define DT_STRTAB 5 /* address of string table */ +#define DT_SYMTAB 6 /* address of symbol table */ +#define DT_RELA 7 /* address of relocation table */ +#define DT_RELASZ 8 /* size of relocation table */ +#define DT_RELAENT 9 /* size of relocation entry */ +#define DT_STRSZ 10 /* size of string table */ +#define DT_SYMENT 11 /* size of symbol table entry */ +#define DT_INIT 12 /* address of initialization func */ +#define DT_FINI 13 /* address of termination function */ +#define DT_SONAME 14 /* string table offset of shared obj */ +#define DT_RPATH 15 /* string table offset of library \ +search path */ +#define DT_SYMBOLIC 16 /* start sym search in shared obj */ +#define DT_REL 17 /* address of rel. tbl. w addends */ +#define DT_RELSZ 18 /* size of DT_REL relocation table */ +#define DT_RELENT 19 /* size of DT_REL relocation entry */ +#define DT_PLTREL 20 /* PLT referenced relocation entry */ +#define DT_DEBUG 21 /* bugger */ +#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x60000000 /* reserved range for OS */ +#define DT_HIOS 0x6fffffff /* specific dynamic array tags */ +#define DT_LOPROC 0x70000000 /* reserved range for processor */ +#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ + +/* Dynamic Tag Flags - d_un.d_val */ +#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x04 /* Object contains text relocations */ +#define DF_BIND_NOW 0x08 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x10 /* Static thread local storage */ + +/* Standard ELF hashing function */ +unsigned long elf_hash(const unsigned char *name); + +#define ELF_TARG_VER 1 /* The ver for which this code is intended */ + +/* ELF register definitions */ +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_NUM 11 + +/* x86-64 relocation types */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +/* 32 bit signed pc relative offset to GOT */ +#define R_X86_64_GOTPCREL 9 +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ + +#define R_X86_64_NUM 16 + +/* + * XXX - PowerPC defines really don't belong in here, + * but we'll put them in for simplicity. + */ + +/* Values for Elf32/64_Ehdr.e_flags */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +#define EF_PPC64_ELFV1_ABI 0x00000001 +#define EF_PPC64_ELFV2_ABI 0x00000002 + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib \ +flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry */ +#define R_PPC_NUM 37 + +/* + * The remaining relocs are from the Embedded ELF ABI, and are not + * in the SVR4 ELF ABI. + */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* + * This is a phony reloc to handle any old fashioned TOC16 references + * that may still be in object files. + */ +#define R_PPC_TOC16 255 + +/* ARM relocs */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ + +/* AArch64 relocs */ +#define R_AARCH64_NONE 0 /* No relocation */ +#define R_AARCH64_RELATIVE 1027 /* Adjust by program base */ + +/* RISC-V relocations */ +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 + +/* + * A very simple ELF64 loader, assumes the image is valid, returns the + * entry point address. + * + * Note if U-Boot is 32-bit, the loader assumes the to segment's + * physical address and size is within the lower 32-bit address space. + */ +static unsigned long ElfLoadElf64ImagePhdr(unsigned long addr) +{ + Elf64_Ehdr *ehdr; /* Elf header structure pointer */ + Elf64_Phdr *phdr; /* Program header structure pointer */ + int i; + + ehdr = (Elf64_Ehdr *)addr; + phdr = (Elf64_Phdr *)(addr + (unsigned long)ehdr->e_phoff); + + /* Load each program header */ + for (i = 0; i < ehdr->e_phnum; ++i) + { + void *dst = (void *)(unsigned long)phdr->p_paddr; + void *src = (void *)addr + phdr->p_offset; + + f_printk("Loading phdr %i to 0x%p (%lu bytes)", + i, dst, (unsigned long)phdr->p_filesz); + if (phdr->p_filesz) + { + memcpy(dst, src, phdr->p_filesz); + } + + if (phdr->p_filesz != phdr->p_memsz) + { + memset(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + } + + FCacheDCacheFlushRange((uintptr)dst, phdr->p_memsz); + ++phdr; + } + + if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags & EF_PPC64_ELFV1_ABI)) + { + /* + * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function + * descriptor pointer with the first double word being the + * address of the entry point of the function. + */ + uintptr_t addr = ehdr->e_entry; + + return *(Elf64_Addr *)addr; + } + + return ehdr->e_entry; +} + +static unsigned long ElfLoadElf64ImageShdr(unsigned long addr) +{ + Elf64_Ehdr *ehdr; /* Elf header structure pointer */ + Elf64_Shdr *shdr; /* Section header structure pointer */ + unsigned char *strtab = 0; /* String table pointer */ + unsigned char *image; /* Binary image pointer */ + int i; /* Loop counter */ + + ehdr = (Elf64_Ehdr *)addr; + + /* Find the section header string table for output info */ + shdr = (Elf64_Shdr *)(addr + (unsigned long)ehdr->e_shoff + + (ehdr->e_shstrndx * sizeof(Elf64_Shdr))); + + if (shdr->sh_type == SHT_STRTAB) + { + strtab = (unsigned char *)(addr + (unsigned long)shdr->sh_offset); + } + + /* Load each appropriate section */ + for (i = 0; i < ehdr->e_shnum; ++i) + { + shdr = (Elf64_Shdr *)(addr + (unsigned long)ehdr->e_shoff + + (i * sizeof(Elf64_Shdr))); + + if (!(shdr->sh_flags & SHF_ALLOC) || + shdr->sh_addr == 0 || shdr->sh_size == 0) + { + continue; + } + + if (strtab) + { + f_printk("%sing %s @ 0x%08lx (%ld bytes)", + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", + &strtab[shdr->sh_name], + (unsigned long)shdr->sh_addr, + (long)shdr->sh_size); + } + + if (shdr->sh_type == SHT_NOBITS) + { + memset((void *)(uintptr)shdr->sh_addr, 0, + shdr->sh_size); + } + else + { + image = (unsigned char *)addr + (unsigned long)shdr->sh_offset; + memcpy((void *)(uintptr)shdr->sh_addr, + (const void *)image, shdr->sh_size); + } + FCacheDCacheFlushRange((uintptr)shdr->sh_addr, shdr->sh_size); + } + + if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags & + EF_PPC64_ELFV1_ABI)) + { + /* + * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function + * descriptor pointer with the first double word being the + * address of the entry point of the function. + */ + uintptr addr = ehdr->e_entry; + + return *(Elf64_Addr *)addr; + } + + return ehdr->e_entry; +} + +unsigned long ElfLoadElfImagePhdr(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Phdr *phdr; /* Program header structure pointer */ + int i; + + ehdr = (Elf32_Ehdr *)addr; + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) + { + return ElfLoadElf64ImagePhdr(addr); + } + + phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); + + /* Load each program header */ + for (i = 0; i < ehdr->e_phnum; ++i) + { + void *dst = (void *)(uintptr)phdr->p_paddr; + void *src = (void *)addr + phdr->p_offset; + + f_printk("Loading phdr %i to 0x%p (%i bytes)", + i, dst, phdr->p_filesz); + if (phdr->p_filesz) + { + memcpy(dst, src, phdr->p_filesz); + } + if (phdr->p_filesz != phdr->p_memsz) + { + memset(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + } + + FCacheDCacheFlushRange((uintptr)dst, phdr->p_memsz); + ++phdr; + } + + return ehdr->e_entry; +} + +unsigned long ElfLoadElfImageShdr(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Shdr *shdr; /* Section header structure pointer */ + unsigned char *strtab = 0; /* String table pointer */ + unsigned char *image; /* Binary image pointer */ + int i; /* Loop counter */ + + ehdr = (Elf32_Ehdr *)addr; + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) + { + return ElfLoadElf64ImageShdr(addr); + } + + /* Find the section header string table for output info */ + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); + + if (shdr->sh_type == SHT_STRTAB) + { + strtab = (unsigned char *)(addr + shdr->sh_offset); + } + + /* Load each appropriate section */ + for (i = 0; i < ehdr->e_shnum; ++i) + { + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (i * sizeof(Elf32_Shdr))); + + if (!(shdr->sh_flags & SHF_ALLOC) || + shdr->sh_addr == 0 || shdr->sh_size == 0) + { + continue; + } + + if (strtab) + { + f_printk("%sing %s @ 0x%08lx (%ld bytes)", + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", + &strtab[shdr->sh_name], + (unsigned long)shdr->sh_addr, + (long)shdr->sh_size); + } + + if (shdr->sh_type == SHT_NOBITS) + { + memset((void *)(uintptr)shdr->sh_addr, 0, + shdr->sh_size); + } + else + { + image = (unsigned char *)addr + shdr->sh_offset; + memcpy((void *)(uintptr)shdr->sh_addr, + (const void *)image, shdr->sh_size); + } + + FCacheDCacheFlushRange((uintptr)shdr->sh_addr, shdr->sh_size); + } + + return ehdr->e_entry; +} + +/* + * Determine if a valid ELF image exists at the given memory location. + * First look at the ELF header magic field, then make sure that it is + * executable. + */ +int ElfIsImageValid(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + + ehdr = (Elf32_Ehdr *)addr; + + if (!IS_ELF(*ehdr)) + { + f_printk("## No elf image at address 0x%08lx.", addr); + return 0; + } + + if (ehdr->e_type != ET_EXEC) + { + f_printk("## Not a 32-bit elf image at address 0x%08lx.", addr); + return 0; + } + + return 1; +} + +/* Allow ports to override the default behavior */ +unsigned long ElfExecBootElf(unsigned long (*entry)(int, char *const[]), + int argc, char *const argv[]) +{ + unsigned long ret; + + /* + * pass address parameter as argv[0] (aka command name), + * and all remaining args + */ + ret = entry(argc, argv); + + return ret; +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fsmc.h b/bsp/phytium/libraries/standalone/common/felf.h similarity index 62% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch32/fsmc.h rename to bsp/phytium/libraries/standalone/common/felf.h index 8fc2005940..bc48578743 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fsmc.h +++ b/bsp/phytium/libraries/standalone/common/felf.h @@ -11,43 +11,35 @@ * See the Phytium Public License for more details. * * - * FilePath: fsmc.h - * Date: 2022-02-10 14:53:41 - * LastEditTime: 2022-02-17 17:30:49 - * Description:  This files is for + * FilePath: felf.h + * Date: 2021-08-31 11:16:49 + * LastEditTime: 2022-02-17 18:05:22 + * Description:  This file is for showing elf api. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/27 rename file name */ +#ifndef FELF_H +#define FELF_H -#ifndef BSP_ARCH_ARMV8_AARCH32_SMC_H -#define BSP_ARCH_ARMV8_AARCH32_SMC_H +#include "ftypes.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -typedef struct -{ - /* data */ - u32 function_identifier; - u32 a1; - u32 a2; - u32 a3; - u32 a4; - u32 a5; - u32 a6; - -} FSmc_Data_t; - -void FSmcCall(FSmc_Data_t *Input, FSmc_Data_t *Output); +unsigned long ElfLoadElfImagePhdr(unsigned long addr); +unsigned long ElfLoadElfImageShdr(unsigned long addr); +int ElfIsImageValid(unsigned long addr); +unsigned long ElfExecBootElf(unsigned long (*entry)(int, char *const[]), + int argc, char *const argv[]); #ifdef __cplusplus } #endif -#endif // !FT_SMC_H +#endif // ! \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/common/ferror_code.h b/bsp/phytium/libraries/standalone/common/ferror_code.h index f00bcba001..98ca6ea870 100644 --- a/bsp/phytium/libraries/standalone/common/ferror_code.h +++ b/bsp/phytium/libraries/standalone/common/ferror_code.h @@ -14,17 +14,22 @@ * FilePath: ferror_code.h * Date: 2021-04-07 09:53:30 * LastEditTime: 2022-02-17 18:05:27 - * Description:  This files is for error code functions + * Description:  This file is for error code functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- */ -#ifndef _FT_ERROR_CODE_H -#define _FT_ERROR_CODE_H +#ifndef FERROR_CODE_H +#define FERROR_CODE_H #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef u32 FError; #define FT_SUCCESS 0 @@ -54,6 +59,7 @@ typedef enum { ErrBspGeneral = 0, ErrBspClk, + ErrBspScmi, ErrBspRtc, ErrBspTimer, ErrBspUart, @@ -78,7 +84,9 @@ typedef enum ErrBspAdc, ErrBspPwm, ErrSema, - + ErrBspMEDIA, + ErrBspMhu, + ErrBspModMaxMask = 255 } FtErrCodeBspMask; @@ -103,4 +111,8 @@ typedef enum #define ERR_SUCCESS FT_MAKE_ERRCODE(ErrorModGeneral, ErrBspGeneral, 0) /* 成功 */ #define ERR_GENERAL FT_MAKE_ERRCODE(ErrorModGeneral, ErrBspGeneral, 1) /* 一般错误 */ +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/common/fio.h b/bsp/phytium/libraries/standalone/common/fio.h index 1f1d8331cf..66f60940ae 100644 --- a/bsp/phytium/libraries/standalone/common/fio.h +++ b/bsp/phytium/libraries/standalone/common/fio.h @@ -14,15 +14,17 @@ * FilePath: fio.h * Date: 2021-04-07 09:53:07 * LastEditTime: 2022-02-18 08:24:01 - * Description:  This files is for general reigster io functions + * Description:  This file is for general reigster io functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/04/07 init + * 1.1 zhugengyu 2022/02/18 add Phytium Public License 1.0 */ -#ifndef FT_IO_H -#define FT_IO_H +#ifndef FIO_H +#define FIO_H #ifdef __cplusplus extern "C" diff --git a/bsp/phytium/libraries/standalone/arch/common/fkernel.h b/bsp/phytium/libraries/standalone/common/fkernel.h similarity index 59% rename from bsp/phytium/libraries/standalone/arch/common/fkernel.h rename to bsp/phytium/libraries/standalone/common/fkernel.h index 60efa30bb4..b193920185 100644 --- a/bsp/phytium/libraries/standalone/arch/common/fkernel.h +++ b/bsp/phytium/libraries/standalone/common/fkernel.h @@ -11,19 +11,26 @@ * See the Phytium Public License for more details. * * - * FilePath: kernel.h + * FilePath: fkernel.h * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:35:07 - * Description:  This files is for + * Description:  This file is for kernel definition functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/10/20 first release + * 1.1 zhugengyu 2022/2/17 add extra functionality */ -#ifndef KERNEL_H -#define KERNEL_H +#ifndef FKERNEL_H +#define FKERNEL_H + +#ifdef __cplusplus +extern "C" +{ +#endif #ifdef __ASSEMBLY__ #define _AC(X, Y) X @@ -44,24 +51,27 @@ #define ULL(x) (_ULL(x)) #define min(x, y) ( \ - { \ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void)(&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; \ - }) +{ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void)(&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; \ +}) #define max(x, y) ( \ - { \ - typeof(x) _max1 = (x); \ - typeof(y) _max2 = (y); \ - (void)(&_max1 == &_max2); \ - _max1 > _max2 ? _max1 : _max2; \ - }) +{ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void)(&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; \ +}) #define min3(x, y, z) min((typeof(x))min(x, y), z) #define max3(x, y, z) max((typeof(x))max(x, y), z) +#define min_t(type, a, b) min(((type) a), ((type) b)) +#define max_t(type, a, b) max(((type) a), ((type) b)) + /** * clamp - return a value clamped to a given range with strict typechecking * @val: current value @@ -88,25 +98,25 @@ * beware of side effects! */ #define do_div(n, base) ( \ - { \ - uint32_t __base = (base); \ - uint32_t __rem; \ - __rem = ((uint64_t)(n)) % __base; \ - (n) = ((uint64_t)(n)) / __base; \ - __rem; \ - }) +{ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ +}) /* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */ #define roundup(x, y) ( \ - { \ - const typeof(y) __y = y; \ - ((x + (__y - 1)) / __y) * __y; \ - }) +{ \ + const typeof(y) __y = y; \ + ((x + (__y - 1)) / __y) * __y; \ +}) #define rounddown(x, y) ( \ - { \ - typeof(x) __x = (x); \ - __x - (__x % (y)); \ - }) +{ \ + typeof(x) __x = (x); \ + __x - (__x % (y)); \ +}) #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) @@ -234,4 +244,101 @@ #define PALIGN_DOWN(x,align) (x & ~(align-1)) /* Integer alignment up */ #define PALIGN_UP(x,align) ((x + (align-1)) & ~(align-1)) + +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) + +#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \ + BUILD_BUG_ON(((n) & ((n) - 1)) != 0) +#define BUILD_BUG_ON_NOT_POWER_OF_2(n) \ + BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0)) + +/** + * COMILETIME_ASSERT - break build and emit msg if condition is false + * @condition: a compile-time constant condition to check + * @msg: a message to emit if condition is false + * + * In tradition of POSIX assert, this macro will break the build if the + * supplied condition is *false*, emitting the supplied error message if the + * compiler has support to do so. + */ +# define COMILETIME_ASSERT(condition, msg, prefix, suffix) \ + do { \ + extern void prefix ## suffix(void) __attribute__((error(msg))); \ + if (!(condition)) \ + prefix ## suffix(); \ + } while (0) + +/** + * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied + * error message. + * @condition: the condition which the compiler should know is false. + * + * See BUILD_BUG_ON for description. + */ +#define BUILD_BUG_ON_MSG(cond, msg) COMILETIME_ASSERT(!(cond), msg, __compiletime_assert_, __COUNTER__) + +/* + * Bitfield access macros + * + * FIELD_{GET,PREP} macros take as first parameter shifted mask + * from which they extract the base mask and shift amount. + * Mask must be a compilation time constant. + * + * Example: + * + * #define REG_FIELD_A GENMASK(6, 0) + * #define REG_FIELD_B BIT(7) + * #define REG_FIELD_C GENMASK(15, 8) + * #define REG_FIELD_D GENMASK(31, 16) + * + * Get: + * a = FIELD_GET(REG_FIELD_A, reg); + * b = FIELD_GET(REG_FIELD_B, reg); + * + * Set: + * reg = FIELD_PREP(REG_FIELD_A, 1) | + * FIELD_PREP(REG_FIELD_B, 0) | + * FIELD_PREP(REG_FIELD_C, c) | + * FIELD_PREP(REG_FIELD_D, 0x40); + * + * Modify: + * reg &= ~REG_FIELD_C; + * reg |= FIELD_PREP(REG_FIELD_C, c); + */ + +#define BF_SHF(x) (__builtin_ffsll(x) - 1) + +#define BF_FIELD_CHECK(mask, reg, val, pfx) \ + ({ \ + BUILD_BUG_ON_MSG(!__builtin_constant_p(mask), \ + pfx "mask is not constant"); \ + BUILD_BUG_ON_MSG((mask) == 0, pfx "mask is zero"); \ + BUILD_BUG_ON_MSG(__builtin_constant_p(val) ? \ + ~((mask) >> BF_SHF(mask)) & (val) : 0, \ + pfx "value too large for the field"); \ + BUILD_BUG_ON_MSG((mask) > (typeof(reg))~0ull, \ + pfx "type of reg too small for mask"); \ + __BUILD_BUG_ON_NOT_POWER_OF_2((mask) + \ + (1ULL << BF_SHF(mask))); \ + }) + + +/** + * FIELD_PREP() - prepare a bitfield element + * @mask: shifted mask defining the field's length and position + * @val: value to put in the field + * + * FIELD_PREP() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + */ +#define FIELD_PREP(mask, val) \ + ({ \ + BF_FIELD_CHECK(mask, 0ULL, val, "FIELD_PREP: "); \ + ((typeof(mask))(val) << BF_SHF(mask)) & (mask); \ + }) + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/common/fpinctrl.h b/bsp/phytium/libraries/standalone/common/fpinctrl.h index 891e8f74de..113a4db723 100644 --- a/bsp/phytium/libraries/standalone/common/fpinctrl.h +++ b/bsp/phytium/libraries/standalone/common/fpinctrl.h @@ -14,15 +14,15 @@ * FilePath: fpinctrl.h * Date: 2022-03-28 14:16:09 * LastEditTime: 2022-03-28 14:16:10 - * Description:  This files is for IO pin ctrl API definition + * Description:  This file is for IO pin ctrl API definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/3/28 init commit */ -#ifndef COMMON_FPINCTRL_H -#define COMMON_FPINCTRL_H +#ifndef FPINCTRL_H +#define FPINCTRL_H #ifdef __cplusplus extern "C" @@ -39,7 +39,7 @@ extern "C" #endif #endif -#if defined(CONFIG_TARGET_E2000) +#if defined(CONFIG_TARGET_E2000) || defined(CONFIG_TARGET_TARDIGRADE) #ifndef FPIN_IO_PAD #define FPIN_IO_PAD #endif diff --git a/bsp/phytium/libraries/standalone/common/fprintf.c b/bsp/phytium/libraries/standalone/common/fprintf.c index a37c4d3e2a..5f6bb43935 100644 --- a/bsp/phytium/libraries/standalone/common/fprintf.c +++ b/bsp/phytium/libraries/standalone/common/fprintf.c @@ -11,14 +11,15 @@ * See the Phytium Public License for more details. * * - * FilePath: f_printf.c + * FilePath: fprintf.c * Date: 2021-08-23 16:24:02 * LastEditTime: 2022-02-17 18:01:19 - * Description:  This files is for + * Description:  This file is for creating custom print interface for standlone sdk. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/7/23 first release */ @@ -37,7 +38,9 @@ static void printchar(char **str, int c) ++(*str); } else + { (void)putchar((const char)c); + } } static int prints(char **out, const char *string, int width, int pad) @@ -49,13 +52,21 @@ static int prints(char **out, const char *string, int width, int pad) register int len = 0; register const char *ptr; for (ptr = string; *ptr; ++ptr) + { ++len; + } if (len >= width) + { width = 0; + } else + { width -= len; + } if (pad & PAD_ZERO) + { padchar = '0'; + } } if (!(pad & PAD_RIGHT)) { @@ -109,7 +120,9 @@ static int printi(char **out, int i, int b, int sg, int width, int pad, int letb { t = u % b; if (t >= 10) + { t += letbase - '0' - 10; + } *--s = t + '0'; u /= b; } @@ -144,9 +157,13 @@ static int print(char **out, const char *format, va_list args) ++format; width = pad = 0; if (*format == '\0') + { break; + } if (*format == '%') + { goto out; + } if (*format == '-') { ++format; @@ -206,7 +223,9 @@ out: } } if (out) + { **out = '\0'; + } va_end(args); return pc; } diff --git a/bsp/phytium/libraries/standalone/common/fprintf.h b/bsp/phytium/libraries/standalone/common/fprintf.h index 4877234b82..4659b76816 100644 --- a/bsp/phytium/libraries/standalone/common/fprintf.h +++ b/bsp/phytium/libraries/standalone/common/fprintf.h @@ -14,15 +14,16 @@ * FilePath: fprintf.h * Date: 2021-08-23 16:24:02 * LastEditTime: 2022-02-17 18:01:24 - * Description:  This files is for + * Description:  This file is for creating custom print interface for standlone sdk. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/7/23 first release */ -#ifndef COMMON_F_PRINTF_H -#define COMMON_F_PRINTF_H +#ifndef FPRINTF_H +#define FPRINTF_H #ifdef __cplusplus extern "C" diff --git a/bsp/phytium/libraries/standalone/common/fprintk.c b/bsp/phytium/libraries/standalone/common/fprintk.c index d07f6b994a..eb83ae74e8 100644 --- a/bsp/phytium/libraries/standalone/common/fprintk.c +++ b/bsp/phytium/libraries/standalone/common/fprintk.c @@ -11,14 +11,15 @@ * See the Phytium Public License for more details. * * - * FilePath: f_printk.c + * FilePath: fprintk.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-17 18:01:29 - * Description:  This files is for + * Description:  This file is for creating custom print interface for standlone sdk. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/7/23 first release */ @@ -140,228 +141,228 @@ start: { switch (*fmt) { - case 0: - return count; + case 0: + return count; - case '%': - OUTC('%'); - goto start; + case '%': + OUTC('%'); + goto start; - case '-': - padding_mode = PAD_TAIL; - continue; - - case '.': - precision = 0; - padding_mode &= (char)~PAD_ZERO; - continue; - - case '0': - if (min_width < 0 && precision < 0 && !padding_mode) - { - padding_mode = PAD_ZERO; + case '-': + padding_mode = PAD_TAIL; continue; - } - __fallthrough; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (precision >= 0) - { - precision = 10 * precision + *fmt - '0'; - } - else - { - if (min_width < 0) + case '.': + precision = 0; + padding_mode &= (char)~PAD_ZERO; + continue; + + case '0': + if (min_width < 0 && precision < 0 && !padding_mode) { - min_width = 0; + padding_mode = PAD_ZERO; + continue; } - min_width = 10 * min_width + *fmt - '0'; - } - continue; + __fallthrough; - case '*': - if (precision >= 0) - { - precision = va_arg(ap, int); - } - else - { - min_width = va_arg(ap, int); - if (min_width < 0) + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (precision >= 0) { - min_width = -min_width; - padding_mode = PAD_TAIL; + precision = 10 * precision + *fmt - '0'; } - } - continue; + else + { + if (min_width < 0) + { + min_width = 0; + } + min_width = 10 * min_width + *fmt - '0'; + } + continue; - case '+': - case ' ': - case '#': - special = *fmt; - continue; + case '*': + if (precision >= 0) + { + precision = va_arg(ap, int); + } + else + { + min_width = va_arg(ap, int); + if (min_width < 0) + { + min_width = -min_width; + padding_mode = PAD_TAIL; + } + } + continue; - case 'h': - case 'l': - case 'z': - if (*fmt == 'h' && length_mod == 'h') + case '+': + case ' ': + case '#': + special = *fmt; + continue; + + case 'h': + case 'l': + case 'z': + if (*fmt == 'h' && length_mod == 'h') + { + length_mod = 'H'; + } + else if (*fmt == 'l' && length_mod == 'l') + { + length_mod = 'L'; + } + else if (length_mod == '\0') + { + length_mod = *fmt; + } + else + { + OUTC('%'); + OUTC(*fmt); + goto start; + } + continue; + + case 'd': + case 'i': + case 'u': { - length_mod = 'H'; + uint_value_type d; + + if (length_mod == 'z') + { + d = va_arg(ap, ssize_t); + } + else if (length_mod == 'l') + { + d = va_arg(ap, long); + } + else if (length_mod == 'L') + { + long long lld = va_arg(ap, long long); + + if (sizeof(int_value_type) < 8U && + lld != (int_value_type)lld) + { + data = "ERR"; + data_len = 3; + precision = 0; + break; + } + d = (uint_value_type)lld; + } + else if (*fmt == 'u') + { + d = va_arg(ap, unsigned int); + } + else + { + d = va_arg(ap, int); + } + + if (*fmt != 'u' && (int_value_type)d < 0) + { + d = -d; + prefix = "-"; + min_width--; + } + else if (special == ' ') + { + prefix = " "; + min_width--; + } + else if (special == '+') + { + prefix = "+"; + min_width--; + } + else + { + ; + } + data_len = convert_value(d, 10, 0, buf + sizeof(buf)); + data = buf + sizeof(buf) - data_len; + break; } - else if (*fmt == 'l' && length_mod == 'l') + + case 'p': + case 'x': + case 'X': { - length_mod = 'L'; + uint_value_type x; + + if (*fmt == 'p') + { + x = (uintptr_t)va_arg(ap, void *); + if (x == (uint_value_type)0) + { + data = "(nil)"; + data_len = 5; + precision = 0; + break; + } + special = '#'; + } + else if (length_mod == 'l') + { + x = va_arg(ap, unsigned long); + } + else if (length_mod == 'L') + { + x = va_arg(ap, unsigned long long); + } + else + { + x = va_arg(ap, unsigned int); + } + if (special == '#') + { + prefix = (*fmt & 0x20) ? "0x" : "0x"; + min_width -= 2; + } + data_len = convert_value(x, 16, ALPHA(*fmt), + buf + sizeof(buf)); + data = buf + sizeof(buf) - data_len; + break; } - else if (length_mod == '\0') + + case 's': { - length_mod = *fmt; + data = va_arg(ap, char *); + data_len = strlen(data); + if (precision >= 0 && data_len > precision) + { + data_len = precision; + } + precision = 0; + break; } - else + + case 'c': { + int c = va_arg(ap, int); + + buf[0] = c; + data = buf; + data_len = 1; + precision = 0; + break; + } + + default: OUTC('%'); OUTC(*fmt); goto start; - } - continue; - - case 'd': - case 'i': - case 'u': - { - uint_value_type d; - - if (length_mod == 'z') - { - d = va_arg(ap, ssize_t); - } - else if (length_mod == 'l') - { - d = va_arg(ap, long); - } - else if (length_mod == 'L') - { - long long lld = va_arg(ap, long long); - - if (sizeof(int_value_type) < 8U && - lld != (int_value_type)lld) - { - data = "ERR"; - data_len = 3; - precision = 0; - break; - } - d = (uint_value_type)lld; - } - else if (*fmt == 'u') - { - d = va_arg(ap, unsigned int); - } - else - { - d = va_arg(ap, int); - } - - if (*fmt != 'u' && (int_value_type)d < 0) - { - d = -d; - prefix = "-"; - min_width--; - } - else if (special == ' ') - { - prefix = " "; - min_width--; - } - else if (special == '+') - { - prefix = "+"; - min_width--; - } - else - { - ; - } - data_len = convert_value(d, 10, 0, buf + sizeof(buf)); - data = buf + sizeof(buf) - data_len; - break; - } - - case 'p': - case 'x': - case 'X': - { - uint_value_type x; - - if (*fmt == 'p') - { - x = (uintptr_t)va_arg(ap, void *); - if (x == (uint_value_type)0) - { - data = "(nil)"; - data_len = 5; - precision = 0; - break; - } - special = '#'; - } - else if (length_mod == 'l') - { - x = va_arg(ap, unsigned long); - } - else if (length_mod == 'L') - { - x = va_arg(ap, unsigned long long); - } - else - { - x = va_arg(ap, unsigned int); - } - if (special == '#') - { - prefix = (*fmt & 0x20) ? "0x" : "0x"; - min_width -= 2; - } - data_len = convert_value(x, 16, ALPHA(*fmt), - buf + sizeof(buf)); - data = buf + sizeof(buf) - data_len; - break; - } - - case 's': - { - data = va_arg(ap, char *); - data_len = strlen(data); - if (precision >= 0 && data_len > precision) - { - data_len = precision; - } - precision = 0; - break; - } - - case 'c': - { - int c = va_arg(ap, int); - - buf[0] = c; - data = buf; - data_len = 1; - precision = 0; - break; - } - - default: - OUTC('%'); - OUTC(*fmt); - goto start; } if (precision < 0 && (padding_mode & PAD_ZERO)) @@ -403,7 +404,7 @@ start: } } -static int f_vprintf(const char *restrict format, va_list vargs) +static void f_vprintf(const char *restrict format, va_list vargs) { struct str_context ctx = {0}; cbvprintf(char_out, &ctx, format, vargs); diff --git a/bsp/phytium/libraries/standalone/common/fprintk.h b/bsp/phytium/libraries/standalone/common/fprintk.h index 907b841ca7..2e271b37e5 100644 --- a/bsp/phytium/libraries/standalone/common/fprintk.h +++ b/bsp/phytium/libraries/standalone/common/fprintk.h @@ -14,22 +14,23 @@ * FilePath: fprintk.h * Date: 2021-08-23 16:24:02 * LastEditTime: 2022-02-17 18:01:35 - * Description:  This files is for + * Description:  This file is for creating custom print interface for standlone sdk. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/7/23 first release */ -#ifndef COMMON_F_PRINTK_H -#define COMMON_F_PRINTK_H +#ifndef FPRINTK_H +#define FPRINTK_H #ifdef __cplusplus extern "C" { #endif -int f_printk(const char *format, ...) ; +void f_printk(const char *format, ...) ; #ifdef __cplusplus } diff --git a/bsp/phytium/libraries/standalone/common/fswap.h b/bsp/phytium/libraries/standalone/common/fswap.h new file mode 100644 index 0000000000..51d16593d9 --- /dev/null +++ b/bsp/phytium/libraries/standalone/common/fswap.h @@ -0,0 +1,64 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fswap.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:35:24 + * Description:  This files is for endian conversion. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/06/15 first release + */ + +#ifndef FSWAP_H +#define FSWAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define __swab16(x) (uint16_t)__builtin_bswap16((uint16_t)(x)) +#define __swab32(x) (uint32_t)__builtin_bswap32((uint32_t)(x)) +#define __swab64(x) (uint64_t)__builtin_bswap64((uint64_t)(x)) + +#define cpu_to_le64(x) ((__u64)(x)) +#define le64_to_cpu(x) ((__le64)(x)) +#define cpu_to_le32(x) ((__u32)(x)) +#define le32_to_cpu(x) ((__le32)(x)) +#define cpu_to_le16(x) ((__u16)(x)) +#define le16_to_cpu(x) ((__le16)(x)) +#define cpu_to_be64(x) __swab64((x)) +#define be64_to_cpu(x) __swab64((x)) +#define cpu_to_be32(x) __swab32((x)) +#define be32_to_cpu(x) __swab32((x)) +#define cpu_to_be16(x) __swab16((x)) +#define be16_to_cpu(x) __swab16((x)) + +#define ___htonl(x) cpu_to_be32(x) +#define ___htons(x) cpu_to_be16(x) +#define ___ntohl(x) be32_to_cpu(x) +#define ___ntohs(x) be16_to_cpu(x) + +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/common/ftypes.h b/bsp/phytium/libraries/standalone/common/ftypes.h index aa097b3ade..1ec12c05a3 100644 --- a/bsp/phytium/libraries/standalone/common/ftypes.h +++ b/bsp/phytium/libraries/standalone/common/ftypes.h @@ -14,25 +14,27 @@ * FilePath: ftypes.h * Date: 2021-05-27 13:30:03 * LastEditTime: 2022-02-18 08:24:15 - * Description:  This files is for + * Description:  This file is for variable type definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/05/27 init + * 1.1 zhugengyu 2022/02/18 add some typedef */ -#ifndef _BSP_COMMON_FT_TYPE_H -#define _BSP_COMMON_FT_TYPE_H +#ifndef FTYPES_H +#define FTYPES_H + +#include +#include #ifdef __cplusplus extern "C" { #endif -#include -#include - #define FT_COMPONENT_IS_READY 0x11111111U #define FT_COMPONENT_IS_STARTED 0x22222222U diff --git a/bsp/phytium/libraries/standalone/doc/ChangeLog.md b/bsp/phytium/libraries/standalone/doc/ChangeLog.md index 376e459c68..4e4f95863f 100644 --- a/bsp/phytium/libraries/standalone/doc/ChangeLog.md +++ b/bsp/phytium/libraries/standalone/doc/ChangeLog.md @@ -1,3 +1,553 @@ +# Phytium Standalone SDK 2023-3-2 ChangeLog + +Change Log since 2023-03-01 + +- modify for drvier and arch de-couple + +## aarch && common + +- move felf, finterrupt and fsleep from common to arch, which are arch related +- move fkernel, fswap from arch to common, which are not arch related +- fix issue that f_printk have different reture type in implmentation and declaration, which is considered a warning for compiler + +## make + +- add drviver.mk, board.mk, arch.mk and lib.mk, to seprate src and inc to groups +- remove un-used packsource.mk +- support compiling with makefile depends +- support compiling drviver only without arch support + +## drivers + +- remove un-used reference to finterrupt.h +- add port folder to implment stub function of arch + +## tools + +- add tool export-sdk, demo the usage in export rt-thread bsp +- remove un-used export_rtt_bsp.py + +# Phytium Standalone SDK 2023-3-2 ChangeLog + +Change Log since 2023-03-01 + +## baremetal + +- add multi-display test example + +## driver + +- add multi-display driver and change the config + +## third-party + +- change the lvgl/port config and adapt to the multi-display config + +# Phytium Standalone SDK 2023-3-1 ChangeLog + +Change Log since 2023-02-20 + +## aarch + +- Modify AARCH32 and AARCH32 interrupt handler function + +## driver + +- fix bug of can id handler + +## example + +- add system/nested_interrupt test example +- adapt gic sgi test example + +# Phytium Standalone SDK 2023-02-27 ChangeLog + +Change Log since 2023-02-22 + +## example + +- Adapt the OpenAMP routine to e2000q/d and fix some errors + +## third party + +* Fixed a flag bit error in non-IPi mode + +# Phytium Standalone SDK 2023-02-24 ChangeLog + +Change Log since 2023-02-22 + +## aarch + +- move BOOT_WITH_FLUSH_CACHE code into CONFIG_USE_AARCH64_L1_TO_AARCH32 + +## make + +- add E2000/D2000 board config loader/saver + +## tools + +- rename 'make boot' as 'make deploy' and move to console.mk +- add config of pre-upload image name and folder + +## example + +- reduce dupliace 'make boot' and unused makefile target + +# Phytium Standalone SDK 2023-02-22 ChangeLog + +Change Log since 2023-02-21 + +## aarch + +- add config BOOT_WITH_FLUSH_CACHE and support flush dcache before boot image + +# Phytium Standalone SDK 2023-02-21 ChangeLog + +Change Log since 2023-02-21 + +## example + +- modified uart fifo test display + +# Phytium Standalone SDK 2023-02-21 ChangeLog + +Change Log since 2023-02-16 + +## third party + +- modify sfud + +# Phytium Standalone SDK 2023-02-16 ChangeLog + +Change Log since 2023-02-15 + +## example + +- add uart FIFO test example +- refresh picture of uart test example + +## driver + +- fix bug of uart tx_send + +# Phytium Standalone SDK 2023-02-15 ChangeLog + +Change Log since 2023-02-13 + +## example + +- add sfud_test example + +## third party + +- modify sfud + +# Phytium Standalone SDK 2023-02-09 ChangeLog + +Change Log since 2023-02-07 + +## board + +- add E2000 MHU module define + +## example + +- add scmi example project + +## driver + +- add scmi base protocol support +- add mhu of E2000 support +- add scmi sensor protocol support +- add scmi performance protocol support +- add scmi communication to SCP + +## doc + +- add fscmi_mhu.md file that introduce how to use scmi_mhu drivers + +# Phytium Standalone SDK 2023-02-07 ChangeLog + +## example + +- remove build_all in example +- set CONFIG_OUTPUT_BINARY as defaut ON +- modify USR_SRC_DIR in raw_api example to absolute path + +## make + +- remove build_all.mk +- add default_load.mk +- modify compiling output style +- add make flash_serial to support ymodem image flash + +## script + +- add script to support ymodem flash and serial access + +# Phytium Standalone SDK 2023-01-30 ChangeLog + +Change Log since 2023-01-10 + +## example + +- Adapt to tardigrade + +## driver + +- Adapt to tardigrade + +# Phytium Standalone SDK 2023-01-18 v1.0.0 ChangeLog + +Change Log since 2023-01-12 + +## README + +- add developer infomation +- install.py update including version infomation modified + +## example + +- all example xxxx_eg_configs update +- all example sdkconfig sdkconfig.h update +- get-start/hello_world readme update +- peripheral/dma/fgdma_async_memcpy/README.md update +- peripheral/gic/fgic_test/README.md update +- peripheral/ipc/fsemaphore_test/README.md update +- storage/spi_sfud/README.md update +- peripheral/media/lvgl_test/README.md update +- peripheral/media/media_test/README.md update +- system/exception_debug/main.c add stdio.h,delete fprintk.h +- peripheral/qspi/qspi_nor_flash add flash type info +- peripheral/qspi/qspi_nor_flash cmd qspi auto related codes modified + +# Phytium Standalone SDK 2023-01-16 ChangeLog + +Change Log since 2023-01-11 + +## example + +- e2000q adds nand test configuration + +# Phytium Standalone SDK 2023-01-11 ChangeLog + +Change Log since 2023-01-11 + +## example + +- add header for some .c .h files in example folder of media. + +## driver + +- add header for some .c .h files in driver folder of media + +## third-party + +- change folder of lvgl name to lvgl-8.3 +- add header for some .c .h files in driver folder of third-party/lvgl-8.3/port + +# Phytium Standalone SDK 2023-01-11 ChangeLog + +Change Log since 2023-01-09 + +## example + +- add header for some .c .h files in example folder. + +## driver + +- add header for some .c .h files in driver folder. + +# Phytium Standalone SDK 2023-01-09 ChangeLog + +Change Log since 2022-12-30 + +## drivers + +- eth/nand/mmc module to add comments + +## third-party + +- libmetal/backtrace/openamp module to add comments + +## example + +- nand/amp module to add comments + +## common + +- finterrupt module to add comments + +# Phytium Standalone SDK 2023-01-09 ChangeLog + +Change Log since 2023-01-09 + +## example + +- network/lwip_startup add func sys_now +- The data type of timer_base_cnt is unified from u64 to u32. +- LwipTestLoop func modified. add LinkDetectLoop(netif). + +# Phytium Standalone SDK 2023-01-04 ChangeLog + +Change Log since 2023-01-03 + +## example + +- add header for all .c .h files in example/network + +## common + +- add header for files (fsleep fprintf fpritk) .c .h in common/ + +## third-party + +- modify lwip-2.1.2/ports/kconfig +- modify lwip-2.1.2/kconfig +- add header for all .c .h files in lwip-2.1.2/ports + +# Phytium Standalone SDK 2022-12-30 ChangeLog + +Change Log since 2022-12-27 + +## drivers + +- update format for eth, usb, pcie, sdmmc + +# Phytium Standalone SDK 2022-12-30 ChangeLog + +Change Log since 2022-12-23 + +## drivers + +- modify format issues in gic/i2c/ipc/pin/sata/timer/watchdog + +## third-party + +- add sata fatfs_0.1.4 port +- delete fatfs_0.1.3 content +- delete storage/sata_fatfs content + +# Phytium Standalone SDK 2022-12-30 ChangeLog + +Change Log since 2022-12-22 + +## example + +- modify peripheral/ adc nand serial + +## drivers + +- modify adc nand serial + +## common + +- Modify the header file name to be consistent with the header macro definition +- Print interface range adjustment + +# Phytium Standalone SDK 2022-12-27 ChangeLog + +Change Log since 2022-12-21 + +## example + +- update print info for gic example + +## drivers + +- update format for can/gic/rtc +- add file declare for pin/spi/usb + +## third-party + +- update fatfs/littlefs/lwip/sdmmc file declare + +# Phytium Standalone SDK 2022-12-21 ChangeLog + +Change Log since 2022-12-20 + +## drivers + +- modify format issues in spi +- modify format issues in pwm + +## third-party + +- modify format issues in sfud +- modify format issues in littlefs + +# Phytium Standalone SDK 2022-12-20 ChangeLog + +Change Log since 2022-12-14 + +## driver + +- modify format issues in dma + +## example + +- Modify format issues in dma example + +# Phytium Standalone SDK 2022-12-14 ChangeLog + +Change Log since 2022-12-08 + +## aarch64 + +- modify FilePath name +- adjust macro definit and c++ support + +## arch/common + +- modify FilePath name +- adjust macro definit and c++ support + +## example + +- adjust "printf" and remove "FT_DEBUG_PRINT_*" +- modify baremetal/example/storage/qspi_sfud/inc/qspi_sfud_example.h macro definit + +## common + +- modify FilePath name +- adjust macro definit and c++ support +- adjust Print interface that will be use f_printk + +## README.md + +- modify chip description + +# Phytium Standalone SDK 2022-12-14 ChangeLog + +Change Log since 2022-12-08 + +## third-party + +- freemodbus-v16/port/port.h ,modify the #include "fcp15.h" ,only used in _aarch32_ +- freemodbus-v16/port/porttimer.c,change the TIMER_CLK_FREQ_HZ as FTIMER_CLK_FREQ_HZ +- freemodbus-v16/port/porttimer.c,change the TIMER_TACHO_IRQ_ID as FTIMER_TACHO_IRQ_NUM + +# Phytium Standalone SDK 2022-12-08 ChangeLog + +Change Log since 2022-12-05 + +## example + +- add LSuserShellNoWaitLoop api.This api can enables the NIC to receive data without blocking. +- modify file format all file adopt lf format. +- add network/lwip_startup +- add network/raw_api/tcp_client +- add network/raw_api/tcp_server +- add network/raw_api/udp_client +- add network/raw_api/udp_server +- delete lwip_tftpclient +- delete lwip_echo + +## third-party + +- add lwip_port.c && lwip_port.h +- Restructuring the directory lwip-2.1.2/ports + +# Phytium Standalone SDK 2022-12-06 ChangeLog + +Change Log since 2022-12-06 + +## drivers + +- Add media drivers ,including the dc & dp + +## example + +- Add media test to light the screen +- Add LVGL demo to test the benchmark + +## third-party + +- Add LVGL library + +## README + +- Add media config + +# Phytium Standalone SDK 2022-12-06 ChangeLog + +Change Log since 2022-12-02 + +## example + +- merge fatfs tests (usb/sdmmc/sdio) +- merge sdmmc tests (fsdmmc/fsdio) + +## driver + +- fix fsdio multi-block issue +- add data barrier to avoid optim issue (fsdio/fsdmmc) + +## third-party + +- add fatfs 0.1.4 and related configs +- port multi storage type with glue, therefore multi storage can be used at one binary image + +# Phytium Standalone SDK 2022-12-02 ChangeLog + +Change Log since 2022-12-01 + +## example + +- add freemodbus test example +- add readme file and E2000Q and E2000D configs + +## third-party + +- add freemodbus V1.6 +- modified protocol port file of serial +- add Kconfig to select peripheral and chip +- modified third-party.mk to add complie freemodbus files + +# Phytium Standalone SDK 2022-12-1 ChangeLog + +Change Log sinc 2022-11-28 + +## board + +- Unified parameter format in fparameters.h +- Move fearly_uart module to common folder + +# Phytium Standalone SDK 2022-11-04 v0.4.0 ChangeLog + +Change Log since 2022-11-01 + +## README + +- add gitee branch description + +## example + +- add E2000D/Q default config +- add test picture +- modified example description +- adjust example cmd +- update get-start\hello_world readme +- add get-start\hello_world fig indicating test result +- update qspi/rtc/wdt_test/sdmmc_cmd/qspi_sfud config for d2000 board +- update letter_shell readme +- update adc/pcie/qspi example for E2000 Demo board +- update lwip_echo/exception_debug/letter_shell_test/memory_pool_test/newlibc_test readme +- update exception_debug/letter_shell_test/memory_pool_test/newlibc_test examples for E2000 Q Demo board + +# Phytium Standalone SDK 2022-11-01 ChangeLog + +Change Log since 2022-10-26 + +## drivers + +- fix bug in get pin pull mode +- fix bug in gpio 4/5, irq num mistype + +## example + +- update spi/sdio/gpio/usb example for E2000 Q Demo board + # Phytium Standalone SDK 2022-10-26 ChangeLog Change Log sinc 2022-10-21 @@ -118,7 +668,6 @@ Change Log since 2022-08-24 - Modify adc test example, add auto test - # Phytium Standalone SDK 2022-8-18 ChangeLog Change Log since 2022-08-16 @@ -174,12 +723,12 @@ Change Log since 2022-08-11 - Modify rtc rtc_ds1339 example to support e2000q,add e2000q default configs - Modify timer timer_tacho example to support e2000q,add e2000q default configs - # Phytium Standalone SDK 2022-8-11 v0.3.1 ChangeLog Change Log since v0.3.0 ## README + - add E2000D/S description # Phytium Standalone SDK 2022-8-5 v0.3.0 ChangeLog @@ -197,7 +746,7 @@ Change Log since 2022-08-04 ## third-party -- Restruct adapter e2000 +- Restruct adapter e2000 # Phytium Standalone SDK 2022-08-04 ChangeLog @@ -277,6 +826,7 @@ Change Log since 2022-7-29 ## example - Modify the lwip_echo example + # Phytium Standalone SDK 2022-07-29 ChangeLog Change Log since 2022-07-18 @@ -294,6 +844,7 @@ Change Log since 2022-07-18 # third-party - fix sfud, spiffs, fatfs modules + # Phytium Standalone SDK 2022-07-27 ChangeLog Change Log since 2022-07-14 @@ -336,7 +887,7 @@ Change Log since 2022-6-20 - modify e2000 iomux set function - modify some parameters -# driver +# driver - modify qspi read and write driver for E2000, add register port read and write data - modify sata controller and pcie-sata read and write driver for E2000 @@ -377,11 +928,11 @@ Change Log since 2022-6-30 - modify e2000 fparameters_comm.h and add set mio function -# driver +# driver - add fi2c configs and init things - create Mio driver for E2000 -- modify uart configs to support E2000 +- modify uart configs to support E2000 # example @@ -406,7 +957,7 @@ Change Log since 2022-6-28 # third-party -- modify sfud fspim port to support cs-set +- modify sfud fspim port to support cs-set # example @@ -429,10 +980,10 @@ Change Log since 2022-6-20 - update fgpio for E2000 - # Phytium Standalone SDK 2022-06-20 ChangeLog Change Log since 2022-6-16 + ## arch - fix aarch32 Bss clear bug @@ -512,7 +1063,7 @@ Change Log since 2022-6-10 ## README -- remove Linux arm aarch64 development environment +- remove Linux arm aarch64 development environment # Phytium Standalone SDK 2022-6-10 ChangeLog @@ -575,7 +1126,6 @@ Change Log since 2022-5-7 # Phytium Standalone SDK 2022-5-13 ChangeLog - Change Log since 2022-5-5 ## drivers @@ -610,12 +1160,13 @@ Change Log since 2022-4-15 ## example - Change the command interface -- Add virtual eeprom +- Add virtual eeprom - Simulate master-slave communication at D2000 # Phytium Standalone SDK 2022-4-22 ChangeLog Change Log since 2022-4-15 + ## drivers - Restruct I2C driver @@ -647,6 +1198,7 @@ Change Log since 2022-4-11 - Add mac lwip port layer to support gmac and xmac - Restruct gmac and xmac lwip interface + # Phytium Standalone SDK 2022-4-15 ChangeLog Change Log since 2022-4-8 @@ -681,7 +1233,7 @@ Change Log since 2022-4-8 ## third-party -- add spiffs +- add spiffs - add littlefs, support littlefs dry-run ## common @@ -719,7 +1271,6 @@ Change Log since 2022-2-18 - re-organize example of qspi test, broken down into peripheral and storage - # Phytium Standalone SDK 2022-3-25 ChangeLog Chang Log since 2022-3-18 @@ -767,7 +1318,7 @@ Chang Log since 2022-2-18 Change Log since 2022-2-18 -## arch +## arch - Modified some parameters in the MMU and added FSetTlbAttributes interfaces @@ -810,15 +1361,14 @@ Change Log since 2021-02-7 ## common -- Modify the function interface in the _cpu.c document to change the core content not to respond when the work core does not support it - -- Fixing interrupt.c initialization problems +- Modify the function interface in the _cpu.c document to change the core content not to respond when the work core does not support it +- Fixing interrupt.c initialization problems ## gicv3 -- Modifying cpu interface processing of multi-core interfaces in gicv3 +- Modifying cpu interface processing of multi-core interfaces in gicv3 -## example +## example - Modifying the handling of multi-core function interfaces in Libmetal @@ -907,31 +1457,30 @@ Change Log since 2021-11-25 ## arch -1. Add stack initialization +1. Add stack initialization 2. Locate the final mode in SVC mode -3. Initialize the BSS and SBSS segments -4. Copy data to the RAM -5. Enable the FPU function -6. Fpu is pushed when irq is abnormal -7. Other exceptions are treated as error exceptions +3. Initialize the BSS and SBSS segments +4. Copy data to the RAM +5. Enable the FPU function +6. Fpu is pushed when irq is abnormal +7. Other exceptions are treated as error exceptions ## ld -1. Add stack parameter Settings for different exceptions -2. Rename variables in different sections +1. Add stack parameter Settings for different exceptions +2. Rename variables in different sections ## example 1. Letter_shell test modifies the makefile - # Phytium Standalone SDK 2021-11-25 ChangeLog Change Log since v0.1.14 ## third-party -- add sfud qspi test +- add sfud qspi test - restruct sfud_port.c, add spi and qspi probe ## drivers @@ -1011,7 +1560,7 @@ Change Log since v0.1.11, 2021.11.15 Change Log since v0.1.10, 2021.11.9 -## example +## example - add fspi nor flash example @@ -1067,7 +1616,7 @@ Change Log since v0.1.8, 2021.11.1 - add L3 cache disable - modify the savefloatRegister location -- add +- add # Phytium Standalone SDK v0.1.8 ChangeLog @@ -1094,7 +1643,7 @@ Change Log since v0.1.7, 2021.11.1 ## doc -- add i2c driver api refernce +- add i2c driver api refernce - add i2c slave & i2c eeprom readme - add driver template - add more design figure *.dio @@ -1123,7 +1672,7 @@ Change Log since v0.1.5, 2021.10.19 - install cross tool to `PHYTIUM_DEV_PATH` - update GNU CC version to 10.3.1-2021.07 - modify CC libc.a for printf issue -- merge newlib to CC tool +- merge newlib to CC tool # Phytium Standalone SDK v0.1.5 ChangeLog @@ -1146,7 +1695,7 @@ Change Log since v0.1.3, 2021.10.13 ## driver -- add iomux for E2000 +- add iomux for E2000 - add nandflash driver for E2000 ## third-party @@ -1231,6 +1780,7 @@ Change Log since v0.0.11 - support linkscript config with sdkconfig.h # Phytium Standalone SDK v0.0.11 ChangeLog + Change Log since v0.0.10 ## drivers diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.c b/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.c index 75fb743759..3020d9173e 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.c @@ -14,7 +14,7 @@ * FilePath: foox_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.h b/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.h index 47bbfb4a1f..13748650f7 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.h +++ b/bsp/phytium/libraries/standalone/doc/driver_template/foox_hw.h @@ -14,7 +14,7 @@ * FilePath: foox_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/foox_options.c b/bsp/phytium/libraries/standalone/doc/driver_template/foox_options.c index cd0ae66d34..6e132fe9a8 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/foox_options.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/foox_options.c @@ -14,7 +14,7 @@ * FilePath: foox_options.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:58 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/foox_role.c b/bsp/phytium/libraries/standalone/doc/driver_template/foox_role.c index 90960fc4f1..b3ed3ab919 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/foox_role.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/foox_role.c @@ -14,7 +14,7 @@ * FilePath: foox_role.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:03 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.c b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.c index 539688f246..5efc3ab35b 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.c @@ -14,7 +14,7 @@ * FilePath: fooxx.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.h b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.h index ad27bbaf05..023bbfbe31 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.h +++ b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx.h @@ -14,7 +14,7 @@ * FilePath: fooxx.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:35 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_g.c b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_g.c index f3a10eec57..a5ce6f65ae 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_g.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_g.c @@ -14,7 +14,7 @@ * FilePath: fooxx_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:09 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_sinit.c b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_sinit.c index fa31af0ae9..2fbe421f64 100644 --- a/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_sinit.c +++ b/bsp/phytium/libraries/standalone/doc/driver_template/fooxx_sinit.c @@ -14,7 +14,7 @@ * FilePath: fooxx_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:15 - * Description:  This files is for + * Description:  This file is for * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/doc/fig/disk_manager.png b/bsp/phytium/libraries/standalone/doc/fig/disk_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc5173175d065d8be1b411482ab0873d5ba1ff1 GIT binary patch literal 160171 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 z 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%0De*vLn266<1vVX2FGmbR=-Vm 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�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

KH1^ZCPZ-4hn~0ia>Cj^6@l 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 byqd=ouc2;W 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

hw=W6>6l;Ijdk$4xV{xDo8YgtBQ_}C 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

dJ^cP{9L4w`^%AE zxxhvGDZ~OX_vfUh&H2pZlOyrI2R{%G-1F`PJb&;9e;D8T);CiobLh8)%2j}ee}SZQ zd$lqUC~9=8aSu`ROz`BYWGm*}-4Aqui)9e8t;Z|&wAA&N!`>v;}2N1ZF z1+2)i2RHPlQn2!|aGAG?hv1|xC^9aAj{DaND$FE-`sBm}a;-8@rb=(*Kn{Z;<15Pv z+y-f+cshu~t!l~^U^FchArRZ zi%~fJ;0s^)Vs4q`VIczpBhf_zEaktoGyUfLM;a6M;5skV1$Yzhe}CNZSO0o+z42mv z=9hjoo;+|Qwq|B5G&vtwUJIbJ>`{U5l8-Y0(iL>WIDGxkhdvbN&!3Nnke$`ttypm1 zKKP$=q;yZ59w712pZcjx$LD_k({cID^U+UU-8gwLe)P6GV|dIH)+}T2!d@QutiDjz zb_jD9uxW$Buy)*%Df!_%VjD12($J@(Hcj>*E2j=)8;-rg_L6NZug4ONYNe?K1uZC8 z-`oZi!%OnQ6U@{@e8!Mh4WK?ZKbNBh>Ps7bIcK`d-i(%sFKWe4=+N*JvM#ev;0eF_Ux=D}~YL@%-OIQSN zo=T}#=}O(khnx;U88#hnHN2s2N%nZ#a9_67bE~o<3&kYGQ!Jrq4_;AF`UlRBtsXuYRiUz51?x_gVjW<)!g@ zrCQDOn>Wch81f)zElI{v1M=qt)Fvx1Z8@A8MpGNpO>`eGR=kyF1CBFqz zWh#bws*7S$7rez3>a(|+GNVy9Dtr3XxOaIYNAo##XTvBjCC{$C(;cy=595A2V}2$t zn!IIt8@y@$rfxP?P3mqw_${s9O@quJUfs%HM~gJ&yT%@M?vNn`pg5;4#GQLHtAn<~ zt+Uih##z#3IV4o9I?btZLTOEKpFnX z9Ru;pzwkjSpP^{oMIc&G%x*#Cqy#x;`u*2nDA9u4%RGd_Q3$ruB;nvo60#TQ>bN+w z9)I*F-;O7rel3fEnIZbR0UOLH{_>u&N%;bB6#;Yb@;DYNDk3AIsr+@s9 zvf|A=msa!6uykeKU{s*ypE8xaFzsBWStUC)IUWzb_x{V zg0Q7s?Jq|J=~hHmTD|?fG)mk@x17nZ*~#H|7d|-+p@3d@fastRA)Ps70`PO{$^jSC z9h!{0XqY&Z`P}o*W$#z!IsWXyc1T(vdNZKZ)2q&3ycp|i>v8*Sx8?K$htNGhq5`{2 z48~q08w>8)SNK%&)O|ZopL;#$S{l!ZJ8sEJ+WDGJdr>Y;Xy(6pt~}sZK5bF1r2mB% zUdSQ*JMX$P4v!y-zJb1^l~^(!_gvlC7w|Z8Adii|G!iT%&p!2HoH_eO96ox4253(z zAk+Y#P*9W=<8&&84T@Y8McM9#M?e0L{`2TR_eT8TU;AtEX*PJSo`LF)i zYV0)Nu%V}MtIS#r*8$*rwsMvAPu7 zb1N}Sc^)4h2@k;7*j$cP^2zBpR)Wq)_UvjK7%KGGX{7Q)eQ+4l@**uN3;C{0?rdx&fOi<)O2_F;0xXB`%Ra8iG2qYa+Na?o zK(mK^ixlIr^5S~q-r*TG-ZBl6$ zAMvXOF3V4YC)v>@WnAUCQ`vGl8CQqi-@JGscO7whnldEMGZhVjIw@0fE%(vpS#fBi zd>=n@Fn;N09*8$DU5v*cdzuFBCi>P9FEOPVAQ%;6NoylK!ZCQuxX;>5kL1B-rz<*2 zcKGn&Yhcw%CVNKkX(g=tR1{p*4$gb(ZtIS*f$sP_KYwRD@ZgQn*KNhrhr;WD4(H^c zh){q=R(n?pS;P&o&a=uVGP`6WEF-0f;%6)~mvkRRKvg z943_V9rte79#t zz7YzUUo$+T;8N}i&wY_|jk&#iN8|X>W4Y?sJe`@Dk7pl$I?i7{A6FKfKS-hL0#Hd8^yZOpRLq{vW9v726p$Y) zdVz%ZR+6Tvv_Q+Ek8P)pC&g6>xiT9sJoj9Tj*TY&?tRz0a^rqC@iz@-P?q78 zOVa@_McDN=5uKzC{Oa#T_D_!>7`dr<*6in_;q7>^8&UJUvcXx zB?3DS?hvfCpEwym{a^oAF?8-s{L!!dT6{hLcJuSm($SN7LShu!MsK@|BLyfcvAnvX zxaB*;kx%Qi?j7<~F8t)sl=H{eXgnS`cpz7~ZxQbnVW7EU03dqX=w#e-;^sIoHHJ*> z#?t&k_HKLnlto4$x(aw!7VSY@yu1+GDCp(f3)UWH5{Ek*cx^lC2g*=`FA}Hj$OS<> z2~xAy!pZ?2W68C9SR5`FG~38)11J)x znU#7c&-KSW&M^3amoBi|MW>jK~zxk)GEU@KW*Omeq(nl_9%Du77LU&oIE30 z#3_i(;dtnBzMS(z1!3w_X*8{tAsdmFAsZw)cR0(fAVW7&pxhN*>kF?f?g4E2tW#j6 zWzzU|Nl(f<={8MO)>RfMyZBXCWEjLPeTC=6c;Co@q;nM+aL($>>pSstGiz}QS?xhD z2v%~qo@m^9Fg-~rSM$s=ll=BIhLn;u#DDcoF+OGd@ZS5ZLws*ukO$2n@Ty@-SE z>C2v7=t~|5?EKDs@u`ga*m&ZhJm(|E8v~OM(5YNE%r!bGcgVJNS@M+t%5=*j|2D>Q zT?A#)ZS{)2rp)8EOdso}&TWm!sgW3;n#?I?=ctQbeCfq(teUJWSJKi*N5;W>M+uev zN~2-jeB;r0@V;ZYXY{we{oS}S>l7&09$BxJ-FURpXV{6UxT-7jeIt&Vbg`Qa{OPIb z7@HW2mhrK1Ub`7IEmVB!L607v>D)%5qP5K@1f`#r?wvOb$3Ob(ACB?KegsWm;HgwF zf$z;s^`m@LCL;U$BeU~im+12Y}^dijmB@kf91h1l7$=cJ#6Z^zQ=Ml4a0 zsZ2eZw2fB4(BM$ckUGovnaLvA#BMDgg%w8rHA-Eo7;CLBYRsBLc?=7+hhvbOs8SVljH}Wz#h{U6kiXH zdO*{Cz3p*udL$+fAB`1S^0(Z6ZyY>$95B|CTO0{i-8QGEuN8nk6gS^|YYY!hP=668 z!e)+U*_DpQPoj+5m-z`HXeGT1^D}^@%Yj_RCx7R+;uF97iQMkX2EwjAGNuy`*=i+# zY^8Fw2f+qNFO3BA(H@~9CuJxq&!7hkxrNXm`EY3R2rZzaw9@+FIl$5087Q%$Dm_Q; z|G1U+f(?Pw{PI$6=zsqFgw+Vq$zU^HQKUG&~&3#BYUYIJz;*9Qw~aATff!EKmS9 zd-o3<7>?Pwh4{&z`bhHWyWjbC_GnqLxgDGH;T-<701H}e;a-`&9CKFy-{ir;>8W_| zJ@1JD!20~mLd?!y$#Nv9b}OkK@?V9btd`!X-FW%smvV8AE7xzo^={r5ux;+Y^kiww=z#yer)AC^U*+*a}}R?4eLm+%1J=ul$O%iuqStCO(o*# zVr4F`fJ2b)FuVXze%HpTd0|?1Deo6AUdj`)Oj9;4u=~)F^N1;5g4MaXS@M6Dcbn01 z=gIih|HuCjW9QGufB37v7>^7O#oodqdZ0ULG=G&x%b*~}UP8BOD!rOUZe4oDrt+fA!EZ`y>aWr;Wz}49q8!-sLp0X%wGC-6tG*?tpQLi zkMb^8v?}ND!ie3v%F35iCVjam$NL12=mN_dZa0uIOKXBtWtp53<9sX?MPN_7HbAB2!p80J$lCMQ)5^EA-x%W^I$)p+PgR8ez(1L%wDtB}d)RA+6RI z0wGC(Z-%K3R%S~=4A6M(98k|=p+61xPFX8?<%^~~_nxro`~BLP;j<0X4422^AdPvV zAxR{ce;VE?cL*TyCqa#P3DdZEFK=_Te1T*oyH}NANXTtl+ih5Pz+*BJnt!R^4cfDY-yB}+E7t$WTB6haSco$4H~VP<-RPa-DdEkgZor-s@KR0k}F9 z$evQ_9y?`Rggekbko%B}DI~~FE{$QiuX0~sS1c?p#tSdL7-!DC37EMfxY-ofBr|}$KP{D zR^Sf(D^|{rQwWp2{HsLNLZp)MOzfJtvJfKqmW93KPzzvnFFyY7e?Ojl_RSa@8;sue zzStn+scB$zXRIS^=PzB3&0Q<;_B^yz1>vSd)|R`yxapSft?*2y=Cf4=R}<-W zTy|{q^Y0Mg=;TcY;>2x-V``#5=3vUVzV&n*Jbovwha&*J!Q2E~ArYkZ^>)M!Hyw?` z$8Ur~VJK9jslU%5dV%duuGBW&%7-9lcyu@`sVlQ{$rmeSH>npOdZJDjts;S& z!|1l;EO1u#8ha3}>{pf+5+FJSWeqS!O~6;eX!VpF=u6j7NFL`sGE|Q4bw5k%2D{Cna8g+_cxVSA(c7g|jD}kn<(M4%8UYZ1)_DWiQRJ1c=al z+1dEaul!Oxf9z;$iuuAjAuoIwV~}k%vHykMjH{%1K!{7 zLGSFw0w8$B#Yk>jw@cn{k>({pE}?Dk&F!5$LfLtt-7RhxCNF7l$!CE1XAvyFI!7<=T!9`U&7(Vo>M z(!RE{8Jp0&gPf_;&95?|Q9y`g!F(`Jl!Y`V3mzpP_E878D{^h+uMRdJAhQ&-q*og3 zEXlMW_kPO8G;U#BiOb3vxpa%GTytO;cEP4EgEBDOnFpjHD;>fp?~AdV%>+7oU?E=J z?TBCA>WMe-(+!!HH+hoaF#TW&BS*z}5l&7dd?NO;ym31qaquYkIQ?=ZKtAcs85wjPAQX;fn)!&%ms7w0M0 z%dxUHmy2{gB~G#0lve7U?ES~Da#0%G@^|ltx_pG2B0-tHJCC1Nqd@sPsxFBiA0*cSgwas|>wKsB} z!}F(Jj`Qc|qPu5+N`47o;eL{ypWc=|t@BHT)@6W)VAi3leUwguViH{EO_?cWGk%0B z=hHge;7~CwCWq1?c5jbX1TO56(_}$6a}*H1w>xMo_s^v?3r}paToj>?H`Wu!M-?g%dt3oU^s>bJ4tV6eEX@F;@GYC#_-h96rMo< zOBenfYVGgu$teQ;Lu0W^#qQQlyHr34%7|CK8h-(+&>_E}-vXxO&(6)p+@*{7L8$SC zB*deSJ{teqZ~R6qQSo=SbR#7-zf{EdCv6!9>2-Ud0q7RoZ>&?bDwum4Fsdb2gbNfG zSCzM-O|Hfa!a=c?Qc z7a)k{Q+Z`x!S4i!xOG*z!%YqeDF+SBzd50e4U@P0513ZJ> z7NaW}(;u9?D9^@N-Jc>cX5tq#kbLzOZg(~Y`{=%93F1# z5iIRy*>F|9`6#~$GKa=huFhxmz2V7^E%GMy3JkE$6LfHi_3YUowz z#`D{4@qhpQ-;En-(ERHUek2|qn}{wH;hR_9%zQ8&D+WQm`Dd@a6ZY**k(ex}$csgJ z9XWHcsOgutmKy2VLQxxW?iR6H6!;*3cf4mXZks$1-RO%k^0e3axylLgxg&}oC0Fxr z!xt4hv7ij}y$(Fl;V{7)Vmj)2u^Mast} zSE?LjNlxjtOSmTOCQSdC9Mb`9T!|u0_O>>R&UAihAN|oe6R$>R{K{Tm zoFUykCTX{nku=05XOfEq=2Hr?JmiwSUGgIvK=QSGmJIppVJdoY#~jP8TQa&8oxD-k z+SyX()uYP^OTFT*3xyx#H$0PerG?U+B$YbKH1XXykvVmzoiNHt0dwj=M=q=fzt`xu z+T_0!OEgAZZ9<&hQARGH#b?tgEhbPOCKjr){!wnRHr{gj3H675Ni6!eH>M6Aq_KW1 zcYJYVZv(qYS}ng-KN+V%xd(anrpq^FDP_od3VuU_`d7J1K#U*j+iv9FhTvdNZvwdf zJ{P}2`_59#&Cle>o%=d_5Q~d5-OqhxWvQWi3!n3l4go&?Tu^AnnYMio14uedH*ZrW zh)=q_gXR|eLoK`$pmsuwVu5TxbgOkBZu7K7+zT`*nK_5w{LT>~cy8H{ujY5k5^|NGPe$g;-`?Y^T%CCNhYAcOk0V5qe<9 z@(TClf#t<|$2wC$Z@GdqNsF@TR&y@I&z@;`l6pWlq}yv(PfyZs2L_SLrPOmNA{f&k zL{+=B?z@neuuY+P4sVlw;&)os;Ui^xL+c#FXc-wAz6w^Wz@}1wjTsREx?=vs;r{r= z58N7m+ySo5IFu_8okgaWXBzj+PA%ndPt(`EGR)b)JjFd6SAl%D%NwM{k ztpk{48X-3`erIDf$;_Sr1ybRVHvA}d0ttISl3AvUZ!J!H;Mdlv0O7`rRAJ)7ipg`} z-Oi|oO4qb)B1Eg}^U0eLT0c``gE2DN7YC+BVsE=Qt}JZC&3D`%1LFsx6970o)JNsm z8E)5bkivb(op-=Tq)nozfcBkMAnPiNE3d5}xwR+2^lee-=4P(M{K7m*qoAa+QSkQS z*=L`RPk#C{aqjg~u|=g|fib;y#Mr*EVr&7>XR8caRD7kCPq?ZP3YUy_ex^O67Bm|! zHVhI-rW}=q353I6izS7I{Ba?Sm9Tl^#=-5#k6=v)3TzHH5XbJ$YAU)i+$<>44fL1} z{91987QWVm+Y0BM%8c+ln?IE*m8tn)i_Mcyq@xpH>$flS+O*8g&SsCA(aNKob4oc-$vd>Rx$4dw1-zQJE~h=Xf|Pgm zo|cvGWgcmQNa$P@P@=$0t6Qe2v~4_W!+X;w&5EyOB&Q`1-}8vrS7y(|-GH&b*EJY_ zL}f9K!@c$b))g2*rq@y-5oHeLsavq5mD`m4mUg!><1zoib;}cR?jTF1JM{u|TiLje z?g)Im3H{?PBW=3 z#i)EppL0i{GJ78~uemQhlYH~nkXudaF!CkO`SxDfLY@V>EzS$W{jT8K&n6RjDe#hK z+-1eWy{Ajr0Ff0WAB&v%%(ps3sGl9~rD2!yvkuQZxy$Js0%XJTFDoD7Q$8#By$V(v zbSH07EID+Gr_y*4K&g*Qep>+xzLY2FFpq2~W;#r(z(`*4zRgh=bpdqAQ^WUrHh+i` z5{xE|;d?6}^mG2pgmdeK@0Y3L_PZ{|tNUH?%ew<{8rkU8pY*{unUs}2essS_yy~3< zsJzTN&mZq{k7M4s>qXA7C65F%otK}=b@$twWRrKi6%6g`E zA3ZFvbzZ&c6eN`t*+Any|CEac|NYlQxBQSMZ*svl?-JPYrU#%i=yAov!{{1E{g6v! zQ`u4ndJOqGe713Gqt_`)j{JF`#uC@1tu?~&cvSeZOId;s%C$5ZZ(bVln@%OI#qy`9 zDH^=DUJ*FDwWHEcDzaX(-t6n|%{kz9J3Dft{&Y(}LpDsyiF-Ad#l!8XORb-jBf)An zy4e#GEenFaJP3x&OC3cRVlMN<{IenLsG=a%t;d`yH4o-mBHm?my7fxoe5pItNoo$$ ztNzJGE{T;_y3GU{N8T1)rtJ7y`Oyg24am-s)Oj)u2VT`7WvkCD#-%*t(RC~CG&43n zMw(S~&|scnT80J&6Ra9p5m-b+Aw%_<Oe1Ik?SzqJ7^2*J^#H^s%v zv+?RHZ^WrrUJc8zN--B{baaE`1ix-PO^YOzt#Jz$N>84~%Gp+}%r5|^FuU&kf-!y;|(`9fCQGN-#t^6CuPU)2?p_} z{3>7T#Bq6UE){_lfpmKgIvJ}QR^s+1QMx3wHm2zD)B zd(y4=;&X>Y3-Z0fecY2rI+u@@L#&OMH{ji$o_jIwq+{F>=awhO@eQer6DZ6) zNejKAvH(;-tG~A=JXiGhdO$}HNwqQNApoTzw?;YJfxhIeV1e?8a?Re1P7-h4s&!1C zMxNPF)V-j)=*<0`L+7nMSpq*Rarvryd5$P$dgYr_ptwa=%#W;I;GtYGEaccb;@g&2 z1gdqn1(KOz(YC|CV6yNs=Q$E)E?D6UR8d4)XgcEFh8RW1tpjnAa+d(7kdyLU=3`2C zL&h{*ojYIsXv}-v`@33i5K7}Sff0&2FUzJukP>S(38(yK@16ps?$Hn5EZ6ROP|~5F zM*Q$mnU}ZzRT?zvipv35?K}rq?T%mB8;RG6L$InTz)oEuZCK;voxQ6Lzw(gpyiYpu zrdu0g+51PjCBtEG0c;*~tSsW+6CT^q)m@o4q!*qEpe#q5>of{C0a&;bc-r{1vADLn zimWKZxI<>-VU|0L*9O+}51B}5%e=A2*>`Cgb#=OfIPV2p`H9#0&2;c=Lsgw(`rHHB z`H%Kidf19nmQp8EAJvA)1~dt`3cC(D6 zeo-MplX}1-!QpPwlC=6WFQ88uzq)&XhIc-9QYI{umUCs>)8uT3_xHENV1FO9;D@kX z>CO#0!`&!~Y${{+;-%eO1B<*CZ=S!9`QWZ7Ik%EBTrdt%lG*09o)g4Ee=BvYy2Yt# z%4gEZr_S#77y~qq3By*1dhuSUPMBm%O(_fLr-%nzLbtd)=0F zW91EbssJiK1vr}?Ka}^aG~(SNa>eOb%jD1UN-Qld<*9XBq{Foand2F)pcHJhUq-K- zGoOHwYo0{uh#RyShh^OOq}RH_IL&W$ljTA_tG`m8$Ox=Dh8w=ypu<0YZ0rmU4CWL) z=h<3!?(J`6KGtws`g(fFJBgukhARnH2&jz~^`1lPM0j$#D}L=K?}SJA>aoVZ8V&YoMm z?8ofFdi?)*`>$usvh+R^TgQ8sJ}a{-%iFfq=tg(L65tRL$sqwkWRR35f`5Z_p({m{ zZgioTk#r?RNFfCkA&rI{O5y~G2o5+QFH?@#Cfxb6?QAdJ(a4zpXfYYbJ6d)i7Mk4H}sc8?B= zBPW-wT-n# z6A);e5xk~p1bcFHCXBp~;<&qhx0o6QWm!5tu3>%d<1)^8r@ru|jL_)7jnZEENrmMH0`@WDD!`075d46cQxpdn%v&E_2Y>G8Spx3c&tnME z$T2-5+X{+CC#P}N@3)&bKLWSgac(rYo9kO`7iK=m-;3ksbh$5U z=v0mY$K(`-=kyRq%aOzSK!H=}aS&9T+-vORa`CNvxpkF%Ap`4Rnl_)G#PM)jB^AEG zsp|9)!I|xGn#OAthmMbQal}{0RUvUrtb8Di?ZLSwR*E~_O|BX>09W|!sozgT*2flV z-Rkz1j-|bQ1+RWRp9>G%x_z^)-CqkW-@kRM-MxRW?d~|80==j_ zvXl=^%w*q7O3M-i*Qg$$6i2`vNrB&vjwmV^9brhP33!kc+EC7pLcDjh7Cf0DA00r! z>4ffJ%(AXe9+kj@v+~hST|cW+Pl2?zzj!!_gTJ!uUZTj`LGAtMl;jrWt?eRf)T6S| z@Hv8~Q#K1;X;z$@QK^-O@FxSw?=DPGp zc*@8KgUVMPY2&{2ewdvE?BGoR?+hK_70P}c`8%_;oRKfrk!Sf(3=&Qvx@2#2n|nuD zUB=?liTW(GJn2%Je7_t3#2EqrdWx6RKA}@Cy=jT(v`Bv3y68v#+f(N4yT{DCNU7?U?kgVKtpQ3Bb5G z#?%L0_sQ?H^a+MC9+Bmmet>6rN}lbyG%#}*zl#30}@FDyy`&H#Ga5oIv$pDR|^^lO!5<{h0~&vEtP*)Fz;=2^y%nZIIFYm@3ph- z9Wu=%Pn9Dsy91{Va=+*YumXcJmdBp?b;nOfSZC9p`Nz?9cHHe?JH6@X8hvB*r=x*Y zo?ALbwrTV9xcbtW79CG*m&;vtIp`RnOLlj++b*)|wsx)+*Qs@zHmA4M)AG2wQBvv* z^guPiiSahm0|+_SOqhrCao}MIzF)w3c;e#ad_m35w>ZeXN5@=t#=U!1BA4d#%Z0U5NAbJ-p!_;hA?=0JXI}U`gH3_9=;vX8l``t> zs&y{29Ixm$+NO|mKUJ-+T*#~zc_?ob9vS2C=hCL|Y-Ejku`%0w+ie}E?&htV?baRa zw>n10KP(H3LLpBCPGelx?wj`R2IG!5)H%1%R?eN_Jm2PY?tw|X9iHF}f;(qr)a?f0 zwH$5Z@xV{WrusaK?E^3BIpK7QzPC?YT5dZj-^S;Y;5&N5HXV;;`N`JyZk*IR_t)b` z?7=gXhI2Z=fiUoM25cXi7_|Mte_#_giRBjjih3W>9$}Gp0tX?qPTlHR448M>j2KVv*+3h`qswEyW-M%I$w;;PR~+5!Vy41hpNyg4X$TC#Lq`(0Q3aJ^q8A*Tw08N@x%T`s zPqZ(8@iXnh#ie%l_DAi*8*A-9{NdNyo8P{L^GC1L5tt>vUW7A?LEAdoZTC0sB2eN% z=VPobPS3Y5|HRLy)CU=!J*y-$5WX;zj^a6#&M*b zyL1_tz@;z`m_wP>QN4NnM%GcfIlqrJ)=nR~ea7k0fj&i)m!E$eJH^QApny-QBx4_- zY>tn1+Sca%w!XFj9!_yS9l1lnXaJg@GW8qvj(8$W(t>hbGO|aHAw6l7oD6J_F~%C6 zvK;vwLhoyluS3!)i4aj((1g$*aCd039R>=~kA{fV06`Ef1n~ zs&&9XM&w6+o}3(QeqL3F(l*?>yAIyQ<6JvxpkmqDp>v_r4$f__a_0J5QR~~CQw|kU zzBCd4j(F=-y8DEq(!wCERP1Jwt#V#Pj$}L*Eh4AAnRZ03*RE>~4tU`7@+uOkQfBxNn*Iw9MZ~x_I zztVnh<$PNpk6RZVz*8AHg~kSzdPZW*Pdnu!aVosJvZJF_pKZ`-F8E0Y%zoRSt9D5H zcinah7?;7%YfoInVZb=UW0%ie46W8y*P$u8fCf8F?Q$9A+>!3xHD@p|^766rB)=d1^h z9+e~iHTwBrX9w!>#Z$M=(}D119dWN?7ap<==9PDVwcgMdRCF|Q;FsZiVR3V?lu4nC z^XUktb_d<*zU%UrFI%AmBB#Yu@ZCU8Pmn{&EnkR+7;5NIw6j9!XT{QjpKIUCt;1=O zzbQW-Dw6Tw&oLZSu+nB{CbJxG5hvVFf=>ft_=?4dnY=KR8RMhTs^cNSXNlru5{jMM6flRKS%yER752!If>Ht_(Otp1~FOzL#ronVHf^8U!orbl~&%mZ{VG{oe0WmYUZ%L zx-`5C(6OveOa8rVtPuB+m0F-8jL^kLY<%TnR zgt8ad(dm;mu|ETGs0*ifcVwdd;a|Mpe(m@EqJ8a;-fU}kx7s+2b&3$V5x8!+J?v2w zxC$`>H$bEgr38$T;+Y5)$y{RCFbK`ze&FFgTOo06S~s4~+6kR+o@EpzUb=R<{luqUZ7;rbtzEo02Ql~Zb(cL2It1C-Ic#r#=fn1UfB1I$##=XI z*yiWXw8}M}5(Ic8_m!Ei|eeMfi zXw#ER&}APOPTKuDx7$14ey6RRJ=?B5^K6uz3@c&n)obW(e0V)QZIz48yh4{R?Pxq? z9_VGS-d?88rUu;JuxAZt)^VyNpuaec5Dd-+aUSI{xX&nb@Ldd>5jccO0n_k!9V5&0 zvs>D-nKEH`0;O953$QK0SbPNP`7pKDYPWenJI8b18hqiL$0(igIJ<7{t^<4X#;vx! zf%A@oe<4n5e|)qF!w{;xo*>7y@7%D&*A8+R5IeJ!U8uspCj?Ol z6uo&yT?2_cNJj;=K1|?9i7zA6i&d8I^nVn?KE@d10b-*7U8Ei*MY-bah-!6GRg%)U zjH_kCH)OMH@vqY$9|Ud`SdGl!uyD3*8C{g7(9F?koiS|)RBzK$i{O#oGP+=Kemcus z&R;y&&bwm=WyxcH`Rs7_1YA0TdytXG{3uiY2s~gynSB=n@W1)*{-5pI>fQE#``Q1z z{n4c-+YGomwPO%m2#bnv06TGUcqyk8Ybjj$W@7XpIMh*dy0v#mAWqVXD=v_?>Gr{g zAJSplZ7*NC(B{xPE5zm7{um>_80Gi;MYZ^Mn$(vzHrF?@?8Z8?&KEpKmrzG`n1G+H zN4!cygL=v>odEs;|7%X=57)_QwAGtVm1?}ogn%16o=PRWq(Qa=BL@(uus5r%z`BXPc6599ru9m>ws`+I&kGOi|B7+c&+u3(puUtU)mll`Q85rw|F! zk+v-ZCn)teRg6AWR|nS*0z4`|k-qB$={Erm#aEnF^4W><8i3Ot%dke_6%f;Ao1?6o zryTCPZb}_4fg*=|HXM}34@Rci>A~0AcSh&iKN!D|HLEUk>5hQ5BukOFw_F`~K!P^h zD?_ArphbOYhfTn2kG!l6(Ynr#>;4v8HS0lE$~JEtbMQPtr_>GC7m#U}BTY}q%UWa- z!$*1HjAK0SN{IKeXWC%lOaS*bnH+&ZUE!>YJATBeg{RzC+Gpy`IHAC#J~fZ2kD$Q__TMYoCa%?mvkP+M_Lelxm9+?-ijY3I%?W$;70EN#VO zYL_+?WLZX~lfs2gm<}IgtYBSSn_e7%rivhlhq@=30w4pXedUz*6G0P!VAj$A?Y0GP*3J%yg{9=)vt?^TlJZp-RwaQ?2!pz4X@i? z^s=(*y&Z7%y|k9jc7V&V1OsX}u{T{Jh`H90m#pXoTKloKyhH zHaZ9)tWLaQ>IfMXpTO{AvoIj_j2&j}*XhZ4`}W%(w%_>=-)O(_2j6aYHxMR)Q;4Yt zX~C#-5SL+X83!apiKQ|Q?oVKDiBk+MgUe(P3&iReN?fNz%@aig)9S`{qT_C*jT$ml zo=RohktcX#3WxgK;!OL(r(SBWKYI-$yolp-ib8=%>t|4-iVjsnD@BVgs`|Xd~ zAOFF(+MDlv*p6^KrW_rcnnQ4OS}_uIwJx1mY+wBHf7Z@jdaBJV!t`er=$S3HC!cz< zz4Gd7z~q;Wfct2tedo<@x2@HUHU|Emx%O;ZT*Q$DALEm=C?TBYd-RxY-;HvK^MR3+ zf!(m&(P)i_>vppVI?S=YwHD{dQNtL1nGUAZpk^dl49RSgRD6pmu1#ksK~Xst{zCYn zU^+=r&wF~)X`DSvx`9K7pzt(x7Q;d}92V)PVsq55KXZd&-`KRbX)iSb0#B%pR5Utd zZfle&ZAU$EDjccMxI3-pE&whg$@WrogzVMnSSc(!I~(aW!<5wRXi;lh>#iT$ZF{cy z+1hA3@R^^ev^@&$9_avB#?klT(l>EyI?ejC?g)7(N44+}WhPv70K2jFa2>39Y?E8E z2!|tNK2xE%zEY!Him*Z)fZ!OXj51yKq%sbsDLc-b9mtef#xlYWZ7kb_Ud#99@r5WI zc;O1&B1@;ir!aKIrgEZ!I7`+uF)`bwCg$243TTer^3vjbJA3X-J9E|_fstsM?IxyF9=eyDB2h_^p^hQe##y9Ybl0JZi*l6}%heI^ zd!o!3}wm6cxHOd zpVz`S+{Q`DOc{gwE{6h}wbRhS@+<{u&eD>_`6-TB99Y`z45syx&edSrXBtEP0W9HT z?P1m75n97X4$h2Fhw0^e2Pf3`rqLO&qwf-yIFO_fZbwxOA)bjdmFrd<`$f z-58|pK^_!-%pc`zchy_MfxY8wF31b4@-li{hvs;^?Gq>6UGgCej@;V8Ysc<|F2Bm} zH2@O2^Sp;nPY<6NhM!m9-aS+6F?Zr#=V~I`7oJ;~X=j(_+6uod8ok*Oa!&GpAbLv;`n76-7>=MhdgVAEy=p|P|TZ3-sDVI{3owjbW#YX9{=`#0@h{L9~L zfA;m;ZR>zMIA6yo9~Gx>sk>Iw={g-j1w2AdQ6k5nhpzy1SX3HrVk@$GG&)^TTAewu1LLp^^9wGgRo4yb-wXFGDWDym+-; zxOlN$dg5w3+yzf4Bme*o_vUnOyu%uKz}cOFe$vdv@-y(N>(Jcm&cm(8vbcX?p5C{g zw6lH;A#}Hsmk~H%5iUpQT23r>|I zwuU|$<(4nU&_{)l@4X{Sqrl;IbIOkKer!YD1);&Y&WbWa0&Y}7uALI68dDur+JVzQ zPAAMZt+=*r=?sqlN?SR*oHsiCMDEJq-ZsOMz(l8$4y+@mD$DiFb=5nE{8#6^-42gz z%`LRA{=sjx#hvZ;_18YvZlT=9$meF_!kx{;3r8*qxm5Cm>|ykS=rU`HFN{l z^YwCu%k!KW0pRo64r&Z0S>h;?&uLW$AfmI(L!=`=r5LD}R9P#@Gh=GHdLR$RE*ToZ}}02@QwB9w2)X?^xl_jx}LJ|G?{pBdb@i&QigR8@M7HX zQ4Y8c9SJNe&b|;s6Nv4Ha^x{(S|hJKIyx>ab{3sM2?W$f>(YL!(!o%;M%hw;1vw;Q<@WnZf zr`QCql2GvFJ4e+s=tdpGZ4~Y}gjPDZuXcnez|S@J!=XRZS=8qF+z;DWj&(Sr?Eufl z&Q{yr-A2FAcKGN78=Lg}CgCNMnpfBz@QBT(Y<0Xx_@4XlL9dsfeKI&OAiN&JUu`LV zumhit4|dX>p8V*MHjrNVgM9L)JZRnwat_*VJ4VJw$3s2%1OPBXFwO)JpTQVEcV?!& zxH6k{nyz^|#lX5q{1m6oH>9WVh$m<1onWk|rXVtg%QpsRvkAV2QA8Kv4hB7zgQIbr zuH*LZM|awrZ+)Zv%AZ{)&X=mrgS>GZtR0lhA&qy#V2me()o^u1BmKtGeJvu&EY&y~ zrP9VZGl&=$CP(;)cbaA@23tmv$(-IiX%l(z0-?vgJ3M~|XJrYad->wI<~PD!m*Sh% zTU?(Ux^X^DSK5MnFt<~U zmZKw)slpP{^sI+u9DObij-Pvtl|Hjv-cO#?buA$9(+C6&H)Tg1ajgIs> za^$CcV{BB6)Z3Mn)9G%JmE{f`j^L^2vJ8cvyc-@QtxGtZwsXy&p9HpZV;c=RThbLU zQ2fql%s`XT=4VuWOVk(OWCY<#-93Z{aY%tI<>H&u_QUqk%DMJG|3Ch3+toWa+kg8H|4IASb1%0U_%&Oq zf&V@NuL5zv_@k^x6##RIrTMnChZ*V>=`*`Ks; ze(f*X^4xM;y?dVyOYxENts$F^VpXQ7KRDq`UiVt{#VSX#9Pvyd19=Z7%b?qF&mNS- zS@$SN9?1wt9!8Gih+#;MC#i?*6kjp}eQ0hwg8z-TgXomL1v{b)B~wRUyr66y_-u1W ze4Ninu)3Tx36<#J4nr%hY)f>2;-=FBPQ{&c@sroqAbcRs%2QSkRSWiku8h@)+ZZ*< z_i)HSem7oz?mR8-l-Hil>j&~r8%!6&*vqm_oDI3QDO_8>{FJwlO>dleaz?&{%WE>& z;p=H?WOcTk-ua#O?$mPopUpkh-h;+7c}g9&AH0jJw2``PgF#%y5r<(dP1G5B**%1J z;$T!844x|;b`!o*k7V#)^chcC6FARqw`Add;(2y%5<`!SO{%BRXC$U6asC{Xaqao| zDY{?U>*4auk<;LK1f9cAeJXy{rH=Y%pJLKD3TC{)`dx-FgFewo&2~w2j@7-+Oo2f9 zue5{oy*)it(}f>w;SXdzD?e#v@#0YYW#pB*4{?@u_PjsN%RatsZYS0?=|`i;F?^|h zAGR}(UJLIq>;~_LVat#e121? zwP?Oc4ic;^$P?IckayI!c8}X8y~KAuxY_>rPv2|*{w|{vphLFhM>3@-BA;XTLg;2lHp_)nMb1^2V&4$q|ttV+$l-xCPx}r*C;FUWs4(- zs4+hssiFLpvBS17JJJ>xGk*DklU_0@L!)_ov6X_qka7cX7I z`CkGLIQckij#xeM#O1cKayDh|>}|JOw?Aszo7=VR2?ofXDXl@Mow8NHAvTA`(w>}C zEGn>aNT7!pff-epuBpr(olgJk*L1pyJ;DNGI_j!GDXAHa=2s(Cp1tD{_m&mzwQT7# zpjDK($`=L}50+aDT}&MToMyzZwzP18K1!J~ ztWyV1X4U{@uS-&!*DY3Rn-9u`mW#7r{7llrao6w6{Ydz8qzBpi%F%B)3=GyrSm(U>?PWad|W8i4hKApxd|L(7~h3(Du z^_M^2?w!As&lTHw6<;c0&*3fbWrx&GfQmZG78waHEelT( zW1Dt=?sKo_^S^Jt^%fnj*|tH)q((GP+b;FFJ=qRvSHbN)I(fIZHrsvhb{{#qb+Fw& zI^Jt{(Jl8dZ})N9?{IzR^sued(Osj?`_#Qb=Vcu_uR^OEbZl?oNZi4E+(rM~MF*O1 z17*EUUE6r`JE%c-d~_wWQ~f)%XAiz}MfX1V+NYfdIBLgSLyUGr+x@(>&ZgT8`l7~h z@S~FfP6mh1P4BE#crpBlj8nc}hsv@6o@fL$&KeLfA3iWB+v463hfX?h?m?M~T$x5y z?vLwk#Cout=u3j>>kJ%T502tvj5hf*3P9?=J+h0m2=^T@~16XXq4Tt`0!mcmJIPsdM2ed{ve zVVi-4GF{W1SwNz!FJ+^1{F(J2Yrb(Rk&&Z=a`x(T$j}L#J5b~o|FYF$|w_{o5Yh=C$_`nQ6vMO&_R9Xp>E5}1-xPCwCzVS^+p0yUSgCkL^-hF zwL04rvYz@sGe|g#zC=1f2e+1W$s@omGAxSw?$jAluY3_WE3WfYzppmbwIMG%#__3p zs(Enj`#E+X`GdZv4NS(4>nn%_vc}GkJss)PkFIfhu8noKhun#;;F0%V1_gJ#^`m&Z z<3K*uP7drLagXBDHubU|J|i2lU1e2}-UdgHwE^a^<04N=V|Qn`dw;ckbmK;BgB@wx znzDpTSiC1+udimWYY>IX^2~a~L$7-n&d3Ev@f|!%UenpZ$#!Q84i34*aVBN@-jPcW zlpk>xeNOq|eV!R~R4u2s4`+4c4HcC{ahiS_XK7_|v3>T;nfA)$bh|<$W^q)fPH+-X zQWF}P1CY!41P4?DbFd4;@1L|C6tc$Bks%Kaf$Ozy-CJ+J|7UNu-~EHHw{O0Az1_Tv zfKD#A(V2xzWoTR`XK>P{$J-=M>iChb!x#$j9yRi1Z(9Q3oS{7OrawX}l2k@|p?@ zd!_cPJ3bg~=dN6C7cM=SV_>+Qz%4+1-l%_x%T6f9q& z(l7^8-fLJSvWkzNJ#aW6aptuHpmN;b)nOnn_!M9H)-Oq&I>-jvmWQ&j#|1kD?=q%> zCjL}nmalE<=kO5tPF>`onkt7wTx9B&dJKJWw$7)cuugNi zYQ)hT;08nF8f14wu-BXyTXg!#ofj0GA@DP>)FFU6`7uOkI~+)Pp|{!)JjBp*j^R^g zq#^0WCx3%!qqYaTF)0ptRL3N2m?k+!{f3Ijf?O=ij0t$Upk9xuQzZy@7}o! zFW<)r-D~SxuJeVTg%vn;n<Ur{hOizQOCa`8PIjR;gEqR3|}24u%4+RrvO+%L3BD zp?5w54K7~346enkN}1j_*M3C7PanE>o};yHe4cfxIKi@rONn#_T~F(Blu$r?0+l%1 zBJYp>PC2W8_R445&1G~3@|Cycg~fCnAUti-hpKqW17_Fvy3>V@yHn}v4M*EEN=!EO zhkHTlyc~m1Yd&}GOxpx^AAI;h8-suRD%&yiapW^=H>qa_*!F;T6B_MP+krAddtu}# z{{!H2>nAux0&`5XL*>;D1#)la!g>EO|cQ@fahH;{P&e4};H@7fDJyc`B~* z$%Q(qC3`$c68_mqNtEenH$T%vCI)F8CE||T;$u_#Oe47oFTZheJI?C=Yjmcq3cEPT zfowo$YuDLPRxH3@55^nRpW-}$GzF(P2SlIwGjFn%PCzMhX+2eb>fzdUI@9BnfAoiX z8wPjR79GskS8T3tqgUqvK7g1GQe-uaaL`oZ6ibYqqi%~x1~jmYQ1tTj))|rwP$qC37tuo@gQ*ZoP2&B z9%(?W4E`Rm#f}-`)!=REmGm&BERnA>S*+XK^gECJ4qq7$50^gT%7@| z(Rbo9AQ#*{m^O6a!n75{EP27Z9d7s0mUjACPV-B9=~^>z2N^-XfB$~FcWv2UE!1;wAjtK9;BI-VknAY~jpaNV^_;QS1$%hepj zb5JEphcZG}(wnzCxwW*k_`_wIN620}m5Cc$dSe1%85xCf0eS&p{S401kE68D>z$)0 z$DEQ!IXcZXdotA)_a-uZ<$|dZw{hV*+yCrQ>86Ooaos*?cQ*FhAAb8r`;|X=vwiLD zTkX!~Y1>o5LQs{yGB!3V5Ow5JWgsxj2s$M%sO2B*FxY=CJ=lX{0Hi8s*T!bK0Zb>N zy3!s;L--Y>eC7;IqPuc#`LuoNrSt9Qe(DSDAOF3-*1r6OXWF%^XWFH6EA55npJ}hW z@GQ>3UVG==>+LqZkuVa7KZZ;i)rnc0pXmi)9L?yH#$yKtxwGa{f!(%A&t-M1rhFyV z_(TaHCco{wVEoiiTH=JwO|`S<7ZC)Uv4t~j9GtuEats=ry>PKzd-}PSm$8ly+SbN; zyL;;vcqrwSH@#`go};StxSfW^lf_A{FJ{SuS&{%<)aBI!$0;F`%GY!Xm@sC9g|ZBu zWis2QGb|@5cxrmns}H!NjB$WH?+1?I~fX?Im}b#$7q04d#`T8 zWF|*Kc@jpQnf6OC;M?_1lrKZ;!0HhB8C7>Q$eK=t3WWLzyXk31iQKbo0>v?(b&|s3 zKfm_lR!#2fdlskn@{`Zf_Q|#%9a2Wyc{rU}(;pt};P9=sy+cQ?57Y4y0dDSppkqZk zm6&4W3jr!q9R!o&3d&SBxYywA?K_<%J;c>0b?78wG;pePKsPrX(cDJK!7V6& z+U80{0gW*Ft}jxycHy`EjEDj!u&8LuV3x#4GiMxBR9jn4cf%{x;r^!7P8o-7eRVAk zq+6Y-?A&_E4Wf1M+{aOTxV}?oG=?X}lI+mU7xz^3PFspDXCf}0KbPLTA9K)A&FDYM zZfR)_XLX5$r@(^4N*#H*g1l}ulPM}>#+QkThfrEH!_L+oH2l)<{CZo!AbjK1&$TVwXppK1>QJf~~6%T$F-~ixvFz8!!$o$r|YsB4FP4Hc-m93fLg=LQj$_aPF z^OHEKH`;q2T}MB`OSJ!xbkf)_$CX0|KA@>@(3;1!z|Neg2e4SA<4~q_A{9P$5qa{a zEHG;5bLNr$rK9nF0Z^HA)VfAsJjlC)hlJYu4wXF>Ycu_@G zr=4e2N{(z0Z=1=>(;6)@i)b{3b>vJw(&o-Mj=YC}!HEn5XE_no&Wwt~d&)%=y1FBP zfhY8mA;wRAKxG<4o$P9F>4kDS$i#E^Bduj2lqsb0n|j!Glh-%zQ0KNI9Z(8<6VcHDw%n5})aA;xlT?MNXVESd+5K4)LV+AO$D+ zd^2g(`M!7Zjc>ixzVr5bZ3Vmi{Btk2b7wBL*_nm5pbb~PDNq>&vnfCOCTlamqw*mK zWu}0(nl?+vBCJBj5q$AaH~`4DYbUDbNL#>{GjN$f+tEo?&(SI0^z*TM@k^W~yN8a~ zNzK58b^s4ZuS$DVgEK`F%NI}Tp75~ngR6YDm*?sk?G*`SWk5*I9NPA<8XyOe=q&Sy z=cSd!wzM$Y=I8t{5IhJ?$HD~gA^51RHSIL*KjdYq(Mfhj!2R(3#JKRd-gyiK_{Jm- zluYG|3(rl>v>!jS(q07FbNi=l1|X+UShFYeDvn{;6NrkVrIpf=I&_U4#$zAn#La!( zvug|4dVhVreeInO+c)05+17XQyy><2dD5(dlKH1yZ0mh7k;E#6C1M7G3KqgF5Xupz z7NfkE^rQ|E}ZIg2p_3uKMrAYxA1$-#CzGdtGK&bj5(a{I9_z0m%rzxX%WfAJ6g zcKhm&ywq0a#@i9dIK^_h@OuI$;)%-_+mC(m_4c{Xy@-JBz?AQ{J9qD5P~BERih#6{ zLk#d@ULMICyBK`;Fm)s3`x_f=_5NDBdFO7sM~_BhG>g%l#mRM)PeE4j&n%wFBJSNI z@UV2YO~CAVX=i4poxgOcUAy)?#4ls~-gn-?q1XdQ16;u%VJ7fXOeKQ>8twPqPrfN6 zG8MFsV8~Q5W4|_oxb8s~@<HGAdu{Fhz3i~ysHLM3!dvx$ z2T~WWmNTJ}(H3W_9Mp&l4T|^?)%Esmjef=fg=c+Xr<}yy_TlyG?dJ85+WOW;)*a6x z+)Ax{@04SleKcF90daWuX@_Mg@KL&6Q)B;Tvy>DE8W~67bRt|{A=x(Q_{g8ONdxCJ zzk9;&A;%fTr7SyFt{F!uP!_n9KF|ayqdXl2{*%s;aE<3Ior7~1&-3IIgNBa4X`|`w z?75Y8;p`=x=8bmy_T7vGxaQL-%x&5(zZ@O!BL}X5uf0y?PtX4L=jPiNfBRSCtbXm) zPq*7kXWE#?7hMx)D+W5v2V3wI7k+%h^==t40?!&Wd2z%SJ~(Hz8otn3Ilw8`5ZPw8 zB%@>$y~f+G+S&0KZ0Q5uQbu@KnX?mQYm3(518@RJp}$^e;=#N8UQTH7Ox9E;UzHcf zle&@~oav|&X#&tsIguS}OD@vdZWCEqq8T28$9oN4*Av5`oYjZr^s?$%-CIWSg~9eISJh4(%4(a> zN>`EVfvy}bv+j|n5K0o8vb9Y*B5_tnCvjHi+ZtH3J6{eQl02x}GPF%FQ()?Gw#y^e z9>|{eS>MgQd``bQ&#DaardgF&k)<^}FZ}qpo;^&jJlkR4R}Z0sGOdlivqPvnf?>)5 z&JIU#P$O2_OxIK^^X|o}qnaH*^0FVDM+ZR$Fq^l+fNt=tdPGOHkF2U|3+LcZei|I= zi}37FTn_oVmpv%Hx66liY)hXy5pj}w9EF?lB~(Y_NE3&ddfhV9K@LTm+t~Y5Af2IO zuV9$&RufuNe(A6NFPNV;c^K-%A@^#_r3SppZ(dNx3#skcJ1k> z+eBaueYE7 z8((QZ^W&dyFFtb_=G$odI0h$p^kb(r^{z0ws65}k#R)&RGTlD?$}{bS7p}HFr-bj_ zY4-;kWouib$Bh`vw6*9-8vdu+go`yOE1?E0N1(h($R3*%eUvBdiL2& z?@BAz@(GE(df`yO+(7@%N4GP*vxSpo0_(N>z%7do;0wOMuQ2&Qeicr`5&SCL?iZ^- zAK`Qw99eecQas2bYxn&gH6148&zI)TojC_Qq|r&Hj6mUHoZI|~> z-Hp(RS^-vfA8`G%FH)U9e*w5r_VCuY`$eKFmRDBVrAwEAVSl=RyPk}OPL6) zWh$43DkB&CRXanEK_0^cxP-v;gL^HXqp}GjrGfIkIkKcnS%qhe@1-OIs}dA?%d~G={HrRGr0e5JdTj zZ%Sb8BNF{!JEUT>U7M^%x{{<2KkZB@gE?GVmK z;yX?rdyq+6s`IT)%z?t*QHFmp_%dd@DMamKI72a z4&ig)1s_Of%{ufU(#cXU6i|U-7*1|@MjGmfeWiUa+j16ab#|_Mhk3Q%p zxHQC_KwR$Rpo*ih(X+skeQx2!ZmSIs>nuL&_rZ(x0jK)fnF;eb>R&c*$d(Ka+aTwd zSAF8(-@@WN{>*gR(aXc)58q9=X7wcQQ(LBj zFP>j%7hvW#3L{UT&>_Gv7(L?Iq5h^u^>`w{OioX=F*Vw5p6s@dFuL#FU2X5{ z-Gh@;-$pyZkpodqac8Ov!eyFp9AY@rB^wTa_1qgD1Ik%L?K!;Ug5YIF` zlLW+%(SPtIsq@R@?Q^eOX@B#tf4Tkq-~7q;<+Xxq9zjwI8_ohXg4|5Cx`i+9R6~8wWmoo^_KjhA*83P(o)E53j>u1cl0AoHVf9 zVQ1E0oX-qBUPc;DW4Q*?_Ii3S&Jhjq?$#t`Qy4ThmSgC7bWU~XbX;@-x>ITyruQ(; zqqjlWbPP>zgXiZLql_)jUYY{o=$~6r%`Gjr6P*wE-L;5*^IZ&R1XWy)aNfIrC)3$3 zudocu7f#RC>H11rN6AqDh8TV8=Ye@lUwm8e_0d^JM^#?C+xzXtjT?EP$z=eJNG{_1 zxqQL&uB~+QZl`p7ethWEzH5|DQA%_IDO=%o%CBHNjB=MpY_B+Tt?%T-Z1{tyfip(^ zI-StiUhCezJ3+wm8olt6e1a?hgLE)Hqov5NM@@5;JXYIJ+Eaco1Z5(Pq}u?cKw7^v zhug5J^nD@Y-o5+T$5FU_SxcwVQ3G*h$ErqkkV%a*k(q`B;4M0LU;Le4Yl|)e_|zBL z&BZfqLIayw2D6)*4h%Q_4Pr-cyRuf@$3TE1*M^FdT7%3p^6S9M!7dHaiBuW$5WK=W zq;+~edjrzu@C$I&hzKS#>4-hG1mUoZQuaAgvV2kQLyUOf;mmV!)eqBKhQTQ?3L{QN zO43ITX>D1L3qWDML0LWM1o-y0pgww}%t5+O8fvM~!(0#AJUDusd|5aA*_PmddWrAP z#96Ke`MeeGzec&IaR^`*K$Aw$%|wR_B@{ ztD1q~{GCo_5AO})4Z~#`IcYfCWM=|= zL0Flb<|vuQ&IZN-?x`a(pH3`#3)%N&syM2HBhNB}*W35;wx}o6xjGBZa+TBI2xf&x z)A!E8a1fSmQ-+V=l;`rNxN!E!`)nCSIZhLMPcw1$#?WQxe&dj-eC5nMgR)%HOHGvd zkT%8}dR>wGL7dm7uTC$12Dmu|S2~w|4ts2ZGKt&X+Gy85_@KT2-n*96o__l2cK+;H z^v!V%q@dUH&H(zxk>At7tQUVJU-=OqIFXoU&VGpL!cJW7<+Sma; zfk9Z|LdvcBEZ;U*V2ZFK&NIt(OGjUJP7Uh$==GX0bnqo`%F`V3qK>N0xcHP;9q?H2 zr7YLGI-);uI{L;qjT*z)U7kB?FD@ehPR&uF)zH#*;xH7M9gP^}7{k9foStm^vy<%> z4&K-9-)&#Jd#7Dr-)$SD-KWRnO95k}Q*8=k#sfA z7H8=Nj#D1x=w!&vr}V^*oif1TJ()m&N2v>_LY5#L;ToC2Bu(XhVzRZ1mzLY-Kl?(v z_T+NAb$7G9^X;23z;^Qs5HwC}52O1=`*a+LEM$jqcb#U%NV`^VYkRL9?6x+g12Hxg zhxWsJ8#t>Ndz{$Ch55W7^whJ@4TN#D-M(`Z$HtL2@gkJ={uEXY&i1Nxa@`U_2iUzQ z$82kGCLiI*fhUpL5f%zCkHKf50in~%XI%;P(642_J|gO2ybeg# z(o&6YzsmN0AK0`$cSJ8jLAzy66}rLE)9#!KYlp*NoaNV41Nf&SP*e9cqFK&v%h#&T zUb+%P=k!0Bh?mYPOn)bBi{9#u58sEMMngYGS3!5$Xq_IynwN`cOPnjpax_4i=m;8w zrwgIDawNl%)l9P+&-Los8a?FIOf$!srU$CCx`2bZLvP(_9+lI9iikEUCzhr2>a?BL z%7{1$*`zh_)hJn4GL3Q<+tTt9_?(j&GOgu)o?Z*T&XM@_&3*Shb}5QZZeDhy<2284 zX2k{a^SSne1AbY@dTC~sXk5B*G4vxcaZbP6*_%VrOij!LPCx&T=Y;eM$4O z6v)WZAe#s-bS>>Ht2XRl_m|2v3l9ynJdT3^9W*-W07OBltE794@|!ogDK9$+4CH{) z6RIrvsd%8vh9j(&FKv=8XLy@(9SPMrkq-GuKc0rgMN-bhJUEB|UekQ{q3i@gj)y_M z&DW!NG<@i=2b7N||Gpu~2L{(**f_!d&~Vr(PW^d4C`&klr@}L6X`67#8z=Yjf>oSVp7{}x9?W0) zawnjbpTlQ~<^1T;gKIKf{NaF#@I3hH8+=Z}&|h51v_h43@KdfWCpu$rI5Qw_it&FTjAC;q;7h`lRz(H@1VYqGT&)Tv|y)YYRwc86r z&(nka|7ftB2mHXf^GmNoMzqsus|SKv`S>Lbw+@o|B}uo{%!|mRqr}kA4yhl#QNGP( z9{Hn(4x@GTI=eknPl}VSyX|Oe!v)1pX@BSKx7y7c*TLaYrv2Ue(X_tMYCdPwRhq=fYI$HFA;{3wkB0cpE*w0*!e3}nG z-(SnDt!q~E*=d^Xx>$11DaEIuUSZ&mw$WyILq}0N^N^Q{CfZ1$7_L`*bo*Z@%H+)vG&Y4knCowIGj=Z1piG;)&>NvCp(;W0x+65s z3P_R(?QPjz$o^a4#9r5QJ8b6`TDx*_w0-{73+;dMcYdn-1DtMLFMzThgXt(dKw*w3|{N7v% zxOD!BHa)+BQ$J15?WuP0;*()q`g`=~-Vfp3=hL%HWAK~~0Lo-#WhD-W0&Sb%3KSF0 zA`Y7hsWYKx56ceo4dVK>hrx2YQ2VT3OB=&*J`b;@T@PL8493g&MOW|%|0q_PCF49> zh7P7dh3F>%Rl3tN^~qEj+fa^Y!6J;pVLlJjyWLp{!!FNjZI$USU3#LOy?8FuAt!dE z^jye02~TJ!M!@UcTesT>@4lBc*zP;IzvFw}CAc1zQ|$r|I;ZjxaMV$Fb4sY3xLUva zup3-hzk@C@{K>4rvx-ZGAUwyD7ZOYx_Uth!a)emkUN znYFsgLp@CW!a~Dx*miHluN|N9sp)z%e+hwsPjtpzLq0Q&tUB!lK3$&U_F?s%X4lQi zZ?@IxMmk20uF{E^p7-lIZu-B{vOzj+)0pXWNYnYnxpwi1i*Xcv;c$FpKno43T|gXT zcfSyB@l(qVbUw%O(%I3e^utJAd8&QtfB5g)?7jQ#`Tz2N-@fn<{$X^-JMUj_?|t-9 z`|#G?_R*dDZ5^8J=l}z!tHSo^Ol0tJ0{*eB(BVK@1A~sOYwLZhdXK|(t}Y>vv)z`; z?`6Bam0Ml88QnI#nusqv19G8Ri zz0M!xIL3Hl0|#(>PuYVu1P-o`fwSNSx4^0)HLlm^zTLLbXRb32jDeej@+>>$K8UlE zImk!6`BE2URDI^*p7;Y~+B~(31IKV#$>UM*O7}hBeB*@9BklU2_GVSp9Q816L z8{XnLmT^UHa(Bmai(*pG*n!Tyb75!KwZbwVIpm(&XKbq&P?zi z9Y6Qdc2^5w%?<|WlA2ipcI`nN)N)oms~ze^MX=b*PjL_Ha~3p?DvpOXMp@N~GTj5b z458q0&T3EB?M&(+q>e%R;*loK^0Wzb{%Kom40=I(?+l0bcmg?aVn#6ZD{3bJv<=sJ z!D@h0%k8)x4z^u5>ab%Au1(7`I}&^7th?yv58itZTe5{eaMGTB>RP@kX{USF5l!D= zamgU*9W?8oz|JxvXt1|;)ciW1%gT1pA$FkS|HxBO6Ao^n7rCxwdk-CW;g_sO=t}j~ z?YsBdTkn3*-g)nXc5iJfGe&*`*~;RIMBA(3 zMUVh|k8^sPJP(qB4Djx2uKbBC9Z54f+TkF@BxIbMnrO@OQ|;wvFSM_I=~L~6=bvns z&n%014EcU~U@F5f2aZdoE-4s24|5O)yuM*wnPO4010?b zPIoA4ysfV9wqO12KW@MJJAc})-`dW)-0A7LHaP`>V8-La9T;{y)1P_Sz>#U{xpekS zyL$PFHU)96z4~l>^5xIA6&%);<+JT8U-%-z7$l5+1$MKV+v6a1FI$iQ+?IlUeRh0SZ3#zV$6eRm9f zE)#m~GwXL9lW{sfmT7wLy_UvtNMQu0n-l=^=!j4=f^&d_Dyr7as z?xtMbfBJAlxfFmO>hSAm^GWY$s#8ZUy!S0kjf0{o@-nYQO zUw@UB<3Uh~CHB#vqWoCO2SJ(qu0T?C^bZs$M%{)GRhxjb^vU2^rKZAPtof+xC|Q)22P(#}CRFDjRX&M0p5&LEcc{UVD)> ztKM41@If23Z!W!An8$&%^M~Gq+p~*7HgPAXACnP=@Z|w|%dc1=*ZbH7w>Qdwk-UCd zj%#4yq&*Zbz8m2Su+FNSKYzZR!EP-rE+M})>lLU2YdLz!K1{QrAl-`|b=^bu?#;8Z zNok)y$_c%J!TZoXq*lwSXK)f>5+!Mmj_S@X?Sq#b7;^BUWMd3titE}UIypL*q$w9g%X_Wj})_{=*bIFtER)6j{7ed6&? zGMcJJP*yLn;%q~&1}{Tv_gN6*C?nJ$oI;WaNfPY-rjrX{d|02V-r0@qM8}f zhta01Q?#$vi=&6m&ll(TL6V#y6Xk(p2RC$9!G-t`pW-~Q0i1TQlf^Q<_Ic9MzLe#2 z>+G~23eI*|m-O=`Q1$(lr?9;%E9neaw{&q2Z%3ppdv5A5IRc)fdwNH zENf87;0UBff__$x#o39rGBeViefo*^((_NXm!7`TE?qpIw*+xBGE$^)>lXSV6c#oJ z)<7r>T_9Aj5gw9^jOaX-VyP*+f>(kh4`*S_m4AL75#*19*j>8&-~QlM`|aQVdi!_3 z@%!!GYHKU!mSI4rHEpvat1viij^I$<48lG?J)h4re)VU6qCNH6EA9M+EA8^R%k9U% z`V;Qm5m-L@=p%Y}?*gL6(KU~D3vk5TN=#=JT)PBd0f!C1)7u+f^C5Q$dl5lVds=q&u%ZtGwj^^t5>)hI<*xXJxoBKss?a0G2C5b|v969nYT5 zuTkkln9lqvT4C0ynjW9Zw6o95Z+Vtw-i)56$4&h@An?m}6wDEwfa&ny1obSPIorlj z4zibPcw8$qMf<5b{I$Kg-oE|KZ{}sHOvQqh`dXDEmuX^x&Y&ZUW|ZbCDq+mmopjW} zhrizL8fCR5zJb3%gHGGp>Uz8J(d`mO93$6*x^L_}JUb0vXCyvG1Q?K$9h^45hO`Um zj3X+ee%58k2#05J7nzfXi;oSZ2vC^t+rs?W7@k_|$HCc<(HP)~lT2FaYCfIi>~0{} zBYzp`#3)YST)X_lbe%5eFk~v;W8ht0S!jRffBf_9{`zWr|2yxaoLs`9f^-9h$o%iwEf|VsJK?o_pnOaNko@ zPzUj!=MQ5o%}7c~F_pg;+3T<1&EUa*WEil@Ck|;BnR>QIA*ogjVmz6gUvR~JqRf;~ z={k-dWEceb>*3wQ6rH~-5IdY`Q08zjMtz?0NIRUu8n)obPq)MN5xU_QM_1Z6ab9OE z^gq&BHFTIya0;t#Y9u1gLfsKxqmJUCx2<4R#+1`RDT6BgN}LRZgQ&4E=;#+ z;5x+-6}Bun z6Va(|N9i_=>c1`Qw>zkOblXp?uR^aH=<(w@@`?Ud5Fx@0pe6dx3)<9qXgKIBst5a^ zP54jznGc36IwU)F>EK&VqEb)vJwMORa;t+4S;`d}l`ZhS2YEn#x^fw3^~|~8Q5x!- zxX#zIv(yY7Z+&2$=lTv-DDM?7x_zW}U7Fdk8u_`|(bJ#*`6t`!pPR*KIy7tEv9@t= z8)HAyZm(TxfAl9??YIBnPW#~2Zrh@e-3b80sXGMVQ5*_|S3^DyfI2#cEcS+Q_B4b? zXVL94Hu0=a9MynXZ2aMPZB(9tREX{l@5izB3l3*j&a}Vv^M9*deD=9^_99OAnM>^_e)?x{Q1)QnsrL3eZ?)CC_u9eU zHilkeHiU75-rQK;9PeLrl7SSy1A3Qk4D7XxV;gIy0-3awqJ+;2S^QL1uIIHEWZNUW z#98KWu$(aI0B41#Qb7Hgaeb6E%tf3|TQARZFQfOOB3o3Yv+A?rml8;s-mO)<&(srf z9$m>4Ev13eDZXL9-`2P3wc&iZK>pm>^KB7Fm6YumY*c| z>s?Q8=X2n&p^6vZgnuN-teEpr&w8@<5be^I)hCP zfb3?lz%nOe5AzaekQ_uj2+~75dUTuoXfRIuFP^Id&=2A%OZ=MObEj3uxuMfM^x~I6 zC9aR+Fv30q+B$Na!IY7s_S92P)r?`hvG~!!N_^x7*&)t#){_(?&52n|o*5pMU$H{nD@9X@B@l*R5(?9J<9R zoSA?w^ki^8U0*QoIyMZ`2tA3c#em7JTj1P7&F1awZe}|4h#p-CE5HD7Jf>sih--6O2XJXBOtQQ@)6UM#wk6=1q4CGllWlfsAq+8w zGvaOqqjAq$ zwrFI!{my^*^Y;J#SHIleySdfIC+8yYj`*tNws2OqH`WofvG(-U%k5|W`d@Dso_?lX zc;Z^ScKONn`7eG2p~CrrX&o}(xW5_)bsr~YadEzFuC3+MlzxxcX$7%sFH%92sNy)z zP(ZJ?>aZAkd}m6T&JC8m4-=-5H6mx|@#3nOz4CR&mO(wFcW_CZ%-i!>-=ib1=6!Hh zvrUM>D$8_n3OVxfm_~tM89tAK0q=gAPr(&V`wUJi*t2xqppN4v_<8z;=d%V_#SKGb zJ=-MwWbaa8U0uD~zWwGmvWK1{)~;)|6D6Uuw;rfcplr8o60YLw(KfTV9HnN*OT4=e zsknEIm~HOuwHK+wDjkPkrc!Cl&dszZpS;qR7lcthl6KqK1>nFDa%k#WC%^(WXrW@{ zTq6aAe?Z}kV&|GG@F~u9HcL5Km!m7=F1p7_w}W%};zb-|@c_IckG#TMZ}PN<`z?ioBij`Bq2by6=}xDW^USvp)#T)CFI|Ji^2e{KKrU;a{ip14Jjg|B5K63D-FMX-~ z;xGO}I{+7-ottd;$or?)SF^2*+`S1gbx&XUP(HPjZKp$rIzUQ@7$*+T)cqjdLM#&{9Kz)};k1^8s5kHy zNN0NUb54F~F_?~pW|fYE+m8j4ql12E!J>YU;)HW-nmjhtdtn?ZK&Bin6aIvloCoa} zK{yq`lWlQ9FVsVU7S0T&m+?J|qtrpX&KWYC*|HwYqm0LKBi*r$F|uIywA@^DxN$Ajl6{Zt@9&c_|%op&K1p19oMu>sim<>!7HMExX6} zbH6T~DgTm|HY(S)!L1`*w^^g8*xvy?%;hkVdcX~&ovzNyS(K4&@W7i6xpHHvp%Z#2 zxdYmD)VvsjD zqD{^O`NFhL5Zalxxds}ie7^<_e5qMIpi{Z)Ai(}{bh2`sGxUh;(-}V@4ve%3c?21D z6k5mf;+ds(9v$arVAt>aMN0=mj^pef`0)~8(NT8vPyfX>x+knQRruXy$Y!YTTq>r{ z=!|O@w59HC?!5yOmRB#B>jNCM3(mOVf5~_9iL;&hixzJ^ z;$JVp2Y?I+qh?~k-U_>=Ya2Y+^_ zUEiSRGBMe#!~0}PIAPR~u}MUOM|e3pDm z*{RfNdYJhZ`AnvOU6}1U4o7#hwU5HA!$EyCp3o3egd*F9{74yt9+1IzVosP*g^zI(; zsp!VD9!Y1b!`jd3X~P&2-(Y*HO)9QpaGgSFRs!>oaeEn^@g2o9h)Wfk&wW<(wgWSn zyz+r*iXUpU&oq{4dJmm{vFCH)F__Mg$|-uywZOWBxGPDg&|SOZ+lJ%g({U^ej*z<^ z^~}YyZDDBzMWS-3jz-@2w!Qo|*6y?qKYYL4yK^JFAWn7Cd?sJ`g(nrqBo3RQguHmi z`X_a!P?FiUgu{_q-wJiJ`mA*&uWhi0tiyWe&Yf&grEpr7FW{}LEVs*7F2L&o2c8jF zapx9KZdR|n_+=6omdii!ZE(=*({_Sf^b>c6C^5etmYIU0hcK8X_oH-}kk6}EE@$0o zZ&RiMDbqJgg?D3Pvt%Q5pUMdI?BW7SXa)xxSzB7fNj=-1edZaQ(<^Dm)YM{NSl_tQ z{vZGMf7<>(|KeZ95nWkyy%LI-@}0tx|2jW;XdtVz2)}_(d0nT%Ss7v0>63y089m~5 zZqGgUY&(1YTzlb#7qYFK`x<}v;RkK?{(78DM~}8}`Zw3NaQ4wT;K@&}%1^c{YqqGy z?OxnJ+1VTA-4Sd*rK_#24cAF8fAZXQxkQ7r!j;NbdYAJ+d7cNj4mCK7-_(_O%0xL7 zEzo0533vKgu>ZJr?V#;Ojgwya`?%455X@$l!R=o;SO94L9{$B+LOBvHD+zrb3qk2h zX`1IIA+4`8RUQG?u^HeiqeV4EDPB1VQgn4*d?ADf%py8RB};#?#c)lNOMdbgS&@8dO8&LXcgZlNW&5MMw(V7gFqR+S*?TD zVJe&yp9q6^cyKlV@7ReiKg+AiHS#W>I5kNTy&ogaMsX0*F92^-INsGk9q=6wtkHVB z>Nu2cUW?}`?5@iIT(6ont2l052O5euEl)aG4*!Rksi!jx^RYbiFqADQI$Cz|d^*ZQ zWjzQ+(VmP9d!x?BrfL-r;3dDxWk*%Lyvf-&&(jIt(K#(AHKVWUX@1JOU%2c`>|{Wv zupRMSq!WJbEWQz}wtDw&1}C)femyGkP6lo>5Mn37IJqbt1L)+E3VBuj_DgudN95i% zssl+&li`$T5m90yI3YG|>m*B=~-Oc)&YD!8mnq3eA0$mwLIeyF^8UXYxYv zT8FEL=;=Y(j_TW1pKI?kKnTyc%)w9o>R0%gZE*s#C6B&BAH1q^rM>)613blhWv{iB zj!OH?VEouW{PBf1#-|V3=HX7ees8M%(ytu0fBA2=+V6a0y{#YM^kJAC3H39U;~3WL zqlgos$9(O{Ywc%$_OD@dpJ=yk-DrMex|Ebt!LHkL?Zqa}Dn=vBRp`=isLcIzC724p zGcUJa?|0JAV-e;6fdg52WS(NsdM=(S-ZX|V&VX@y+RkXwwLk06`?ZJ9!rZ1cFGa?or4F458D4n& z4zuxw4u?}vj_`FO?zHvZjxR1*p93ya?d-)%ZGLen;-OO_FZdFdd+52v%lg`Cd-I!L zZ`+%z)K$wT_IGzEQwPDybZDx_UM~`Ksuxb>AwRt;tZ~$B0I-Fp!LtshBXN#gShh~E zqk@j&dGA*`&YoRq%PULdAI*yr@{UT#&sj<%+u`;mu6@eXIJ8Tzl+Ih;r1xd0Nk^8; zfw!C(m^gVlgPsS*jbIJ7WpZk~&CSom;mmiJahf#XD)Aj~u)2Cb^5fDGM-^QF@6G_{ zE?sC(T)y0%hF4#C?bY_V&wjQ&``mMFe%_ImDIDB;?RS3X*V{k+r~kD5yMO!3h|@^c z8~ar%J5)N-jw~ROk%3xgDn_N5%Q#SCz^6jZHZpu9L@mu9fNN5z01czDftq>fZW@v+O~hUZ(X$wg)gJp2M_e6$h4UT+Rm4 zyF_Jh_b?3Frc8a;Z;-#2@$g<=3G}(QZMMu`IjUl*f;uKTha>CDi7QHz*1FAg;+SdW zaRkekjbi)YOTSi?cO!^9M8?%+e*8k-_ON5+k{1GRDFj-`)Fr1pP1#D`z*&1(ifl%vEX%H^5dLNQwHW7>_2Mz_%V*sZtiTQ zgX=ps4uVL->?A@uqKcmZujIY>Lot!LEQO*z$=cq59-ciXYIHHOKb7{R#(HL~&0vHV#z)%)8vNDEPqi=h|5@LXHmNh&Ih5I*_kQFhb2tiy% zP`MT%=9Brua9kUo-Y_Bmz2~I)GmQ(qE5`D4jLAbA^KE0ea`a?B>wKPj{>4mPe(=GE zIGd+!C7)=U0H5>i(v>IM(%Ex4U%m1)0z(-v!NbMz)IpmD_Mz==@3aXON>!@e%P5b| zm`*?xl7eVr{?ap{ZWZhibdafRt4A@IL;1CSxD-)JuJ#j#nbvC=$Y5T}>!FXZ_UApn z@zb-@fj83w)LRY=Wk8R7f|qu$;1RW&7jo@zb$t zICCn|6CD)bwD+v@D^L10u+=-a;Zt}VMHK#&ict`rOIWjg28ucg6~I(TUZhhXY#f$7 zIXww~qr7OFQzG(uwhcpuRE|#ludlB)zo6wZkQJOQUsSO3kvHqfXNRHqt?HUMbuAW7 z8#1AjD#zLW7*Bb5K)Y3 zn>9TS&uwgOw0n2&#i4fu(_I$Mo;}|#(2;uXh3DJnKli!z=}&*EJ$dz+HZ$W$>I6>e zo%Zc-f4%+lfBxUJfBmojReS5rx1wNuK@EU|L#MGKSEmJsw2w1Nyzq^UaE~q-N14i_ zcA})Konjq4D>M%$?*&?!UvHfZ2W-BU(^bP)!#|$L4-W_2Lv%ODiHy{z$Q|)VPpbFRL9%py zt{0TA;bYs77h_VI)!FvKoBU;Mmak4xm*}W2E-q%>Wb~e1lx=5~=h=B9JWy><9XTl7ExSmgvt*f0!Efzux2-K4)9u~N zW^HciT-NfRjHqHG)W^c%I^Dd?X>rJLW_*!PopT+je9oP8d(dp}2&ea8w;kZX#G`Xph2HV^(e14a2aP* z^h4_MzIf~7hgs!WQw$&cENg(nr1c5s%x3Y(V0_6|*CylfJx^fNvvq{M0i0!i`iB}5ngt0F9vv?T0s9ppd?1k#61OvP1XCs` zWf;*Ur9B~Fkcgz^Z}5y*2)Vv>*#6?{x7xq@?|-kod*f!iaOrA$>DAA+&%FLhd-~bu z+n2ub6YZ%dpG(=rFqXst-uz;Z+gEMhUu*Yo-9-V_8cMhRQbC#CUNu*7T2(wz&N3RM zXh3%`$TEw~Z*000V~budtdc2qX{vK2Q;z1P0l=aCjx5T|!WEcc>nG8(T5+<)81^yyH$QKTg9)_B+SOi1J!X6 z4`uMgr5oy>AfSH5C7(Hj_r;YjRJn2g?(RX}{x4_sIM+9C-OLtkPLW)^bgnI}EJQ(C z4?bBsE;{IT8mz}9AFd%i#mQ3HrsofiJZGuFVSPtGG}56%5yf!RW|e}Yl{M-LSJH6; z@HT!_3Z^);wP&7xt}S7JK79XroYb%V+1Iirb@|K+j_kGe{0lF(XP$krz53d#ZFYVo zII3{cHt*kUzxR8;*Z$}a|De73?YG(;97c_$dejdd2H|&)=qSi&hPxfa`tc)Z>|IL z6THIH*A>@p3+0gR(eZO1SdEZI$`L?~xdC?j7UUYJhnjhXJ}s z57Q?RII1tSl)~46fFo&(@>DWrdu&^mDX(={ET;^Kae0zF4?`Icvz1H^q6x*T4;8$J z<(gjk?7_GmGUH-pkAzdA^cT`1&gz$3P{%0z73XFsSf-sTr?s7mre(wmC%j2PM~Bg- zG4Sq%X*=YV`l_9hRrnL1rr{qnJ7{hjnDyx3OndHLtuyLyc*XR}qO=GM+-tXbu>Hax zyKe-~t5Jg%qi}qA5aD^CvlB>XQ#Hob=}?6vhY!KAy0kkXrC&9GE0eMFmId z9~;t%shXp&h0(f+rXR)KyGG( zclleq2}>N$$o_Z+w=7)8U8m8`=@@NLf7k)ds3Oml$FXVT5je%J`oMQYv}-QIa}R2l zOKsyHZ11=wk}o77@9H0Pt$U37qH=X2)fIF|Gvh@k6o$w<9^#XBp5j2&Hgw{tcv4+0 zuLmvEsqT%VE^L%<8yyi9>*0N9F5AZ0FLEXg|8p&_J{G$86xux{lx$lDc+<8dw*G@v zY9sUt5~OJrW=+b`W99il4IdBsEyKD|r|Xo-ZN0-IpI_@p-=7MIK*z z8=I;D7GGqxgQ^amo0?60_DZD=^|9$)mS!iyK>=|qFKN5v1?6#U1{z3!K^WV-dH0QX zKHA37#Q8xmGin6m$rO&%xMs!Cm~NQGe->y%un;TvZc>XwxsB4_h9P1gb|D^08VV{q zM^0T(@gzL4$n_K$X1$C(LTb z>baJ<Cn6MgeTJ2Qej--s@f}R2)HVDPKn+j8P~qTs+?{Ts}j(t+u|g)|Qu-+mqLx zZI`cHZO=aUVw^hAPeCd^VAAZ-a%NH((p-)jb!lq-|%jhsTq7}G_m#O`-#}u89r>{NJ=5So4 zg9gKC)(9=>q~nc`uD1_9cppC9$d^f6PSN2{*$7H+m-ukBwnp6GXZeTnGSyGIgTrzj zO&ceNb9#Q1<^FuG8#dl@bz0riw5ON6t~Ya2XZM8NMWK#5MUR~MM!yGH<7Dk|g#Wll z9m1Q`$F(B~pd>U*dBH=C6uU30dD3|SR!1qOQ5Gr`#ojk%9YuZX?YEJU?KU?v*KXaq z)mCw;FI>LVKL7d8x1adQpKM?G>W{alpL-eO<=0%G10AM~_0{&xZ~R63rC<8j?YDpX zx7)k#y`NDG`AI;0xjro+~Y&k z{HwB!?njqfuPdMN{7W!>8686}Qyw1WtC2>I&7QQ{_L<<-iIOS_z6LD z0%z}4Xrij2^DRjDGXf>=3f7>^Wb9#3rv^683sI>rc}C%7;y88i~9kl3*8$=R%oi(~;0`Kj#Q@(sM2pz`{@(Neg z`tY!@2SHd!Z-L$k4{gm?_5y=^E390nt@7D`E>tU~3a{lbTAdy6K8hKefcylfJda!q zoGA07wNrlbaz8VL46e9jX(cab3Qv|840xe}{Ae?PLE#y|Zm4)=i+rO~=&0kigG_DX zBdl)hwEJsY?e3k8cH{P4j(hF)-PLxJ^PPL^ZHqK(TTba8we@w^?@P5w?oZq1_EEcY zf2ZBLv)*ppS#7s&ueE#YTWxJ^gM5B7-*3yi_TN!FXLxI1%?>P54P>_689J^2vR()( z*wZ%P%{>X^5^?G@b=o*|@GpE2{^Pc;%c)D8C5CSO+0X$Ea&Rp#_xNr*(?O#MOW{d= zV%Gc6XXvOj6@3|1kWjpdJUd?oc7zZ_u3Wpxb3VZd4(69O^vwkV?@Z* zkpo_JG*)L`+u6(YTrct3K`~2}Z~G0wyPduwOFi4)IeFs%FZgH#qck?1b#jh6PEOY7 zl}8K+hrkJ>2GJ2T9aQ%ub2=`=>ewtd%MBx-3}VP}L`F`X4x~&B%F4)bdusN$J-cw+ zUOF?zlZu+tUqYas2;)*2Xaje!brI6UWiz{n~9 zvDgWiYYwlCdl)|m=1KYk1b?zU{p=Gcf;p7#Lc4JF$#&%m$JM7pJj=?|G|s{5+P(B( zW@jdwpS(Rn@Us6W^@oNsmXxM;6}R=emQ_00*{E<@3JQiXubm7T!Jf4r4)8O4_9Sha z&S8gNCNdb`&p!9u<9g_MjQ8B}AmbIILm$B0+1i3HP?#L{ROfKcGqOW*PDf00?;Dq+ z;7cCLCPL>X{s)RZ-Mdq>qr^a#YX50#@K4aHqGo1nIc5{4f zPeuvAkz~rWt4!oNTL(?8vQ;qU!Id*S8RGxB|~ zzR@=C-)kGIYwhcQ_UG+a|NXDD-}?36Xz#!GUgTa!)e&WJ7DES}olX}Xjoh`To{BSS z+ubPJ5z{!Sc7W-XtE@YZc*wUNwl8PWW%@D89cqb#>BOOQF|RbN4uuA~46V;}RI|2J zJ_0Ej6+v#?CQNulc%PEAK+6>4N>+^`Dq8RthxturNJohqmnrnn`MrnEM+TpHK$XF{ z_^y(7ozc$)+E7tL*XH%UpRL2IUjCpB#6Nln%kaJ7(ff}F<4t3}j?>;I?g!-!2VsbD z8RW}_|E)v0RA(bIHFcjy){=8~4jwJjVl>iOyJ|rX(D;!7=Be+M$n)AC3Y?w=m z`VriijXW7t(O$uS>PP1cy6`pi&g>W99YyQes(o9)h>wf51i z)qKVA&fV>7`M875+;Nn2mkv5QaPQ!xZD6<8H+FGAx7zCZ4(axATKC%8=1#jq+-)4% zHOku{|2DqJA@v6Y?1N6YaM+#6NGW={W)!6+ zcyZEk;L-E`#~i&J&)xn#8XnDKD$j-v=MNGd((b$AFbrQ;81U49C%DOT!IkfX$JwOX zb%tj|`2Im3S?&B`{-c52n_dG_*7*A`WEba#Pij1`7?%qe_FY^Y-o#@7K@ zU84s^56Y=c9iF2J*OI`jGh=Oc{Ge^&93GAzw?liHQ#i!)b8Y_YLYrHdYcq3GZ4qNX zHSZ?lv~voBKjq6$zOj#CcS{v)ew3F=O@u|s(JrS-z==ebkhWc;mzMy*#c+@gc9Aj? zozb7&wny3Tf3T0xj<%;>`*eHlv#+<$z5c}*b4SDW>>aM&r=6P^=y7N<9|y=Oa;G=; zX{*kdb!QX}{Q6;l`o6j_p0rIIjkSE`=^&dAlQ<)3J3Fpzad)ulsMF9Dne;Yz zT`vWduy)4sxz2;vafEqpoaf;*I#LElzettxcTW%70yI6uiI{-C?x*SggLm)VgO_%( z>4iU{L~6=&D!ntT@VMu!FZPVc4^y-4Gp~Qa#LzrR8_$&yG#)L0C!|rjF5YBu0LS!XuBkvy)N#5BdQBd-$sv z72V$6X?O43X*X~N{o0CUNr&20AH@m$BcpWU=#02OUEn~z6mVZqjFTxYI6TW+3cgBM z*)%AhF0}~$X^+ltroibyicd$M7w7!|g)ikz0MllB`#axh*RQ`H=g<9o|IXj~&)eVs z2Y)}tt)^y<+NwJk++E8as2_gxQM+^RZo7Z)KFhpe(qoNPHp@@*>S*N?jsK_-w?*?G#r65I?e#( zAq@^FQ>82n=Ji~9{U#v6vum8YJ09uEC^ z55v#Z-^2NPD5vV-eb3*|HIwC)FnLe=pw%N)Kg>52ucQC4XgeeYgHyl4U|9xn(q~bI zLtglyzz3L-w(wa^7J&nz)PDw@Rp*wX{dgcchl{Iv3$IF0rs|2agPVGd=N$NRYx$*1 zeJ&4m=dhLlRN=$z0Ea+$zqPToB%p8{zVn*jQMT^-SmHr=(7K^800JHnN6r9dA7bk!^)&Q-ub$p4b~G}aqrRjUz+yk>dpJR;~Du}U*Brmd(hjZIJ7+-9G5E5CLPG6 z=Wx$yN5jd?Uri^AY+9OnT*l*)11Tt_fze>hde^Oat0mT*W0C6QVn+_%NE6@!EzTC7D69`euO(XIGB-ofx&H0 z)tQFWt^SZ`zWgygJ=SJ17}GcdzK!hkB*_AVg=(BM7N>YiPV33szCfY^*GL?V*@LlQ zj4+I}GCSQ?rcc_+{Aqjb*~#|lm(I1 zy2h0=j;!lsMrTLbkQ>hwE2aZw!FB+{e0RqGl#>+c|u~L4LZ?A(2%y#mt0)8 zVUUO_duf&t7zH1sN(l25(M3Fo4^(y-!oz*a7;hVUGwoa7+-O%n`}y|zmwvRp_|j|O zS%Da9H$M8XU4QSbtbp>xAoplpm|Ki+Z)|P013Cd`R{S>mnFo%jBNr7E2r5J%AsRH> zY1=pyckkSYLfYNk1|H!CBn)YDbP)O)y20o|X-L~Sy!Ysg>siK=$qeGD3$^LJ_NY;> zqkITq<=h#-@_X@HD8X~-?W%N~VsZ+5eRZRaPJnaYUR5CgqjYuaCvmAGY54`?7_^#i z)8OUVmtKuxKh`A%j(TYh+;hDBjc>NMzx_6}sZa2^rYrbCg!EvfsiC*mc6q4a4>P*1 z&}d{;z~G6t?NLr2T@tPyOzVcy)n=~`vKz+Q+FCwXu)piH77qCUr{X!C4V=E|q3_&JS~_@b{1yVOb8XqmkaANm3sArynBMp}#k2!W2_2z>Z=@cF~g<+FlL)x#0u)XQNR;kltYhePeE@Ms{9 zqlD@rg6*tP)T+y9>2G_vO8LVEQCxYhv{i;YpeTE191tPL>S6K?#F#yt#`?g2imjlbxFJb9SUAe-5|luMprylHro;A6r2$KldI z8Oi`j#>ki2;aBUcHK~rI5=(pO0u><6%5ayL`M95Sxdp{bFP&BOi*nTQAbsp~DRXo4 zQ^@N~UizJ1_G3G9S=-t9wbRNVoeH-PaoPDr+!#z_CsUY}v*U?*XndNlOF7%=r=+*G zbx46@z)#jyTT=N>!(`fQ9lqJ0Plt1z{if~cow!72u!N1e?Ig&1g_{A*kjdhyQQ9W# zIPb`>4!nq+qF!;LTsuQ#usvO`R!6hS8*ab6+S_kPUEBwjLHb97&wKb@X&w!>{|5~n z|DQDUb_mmO8;!Rt+hqL1aIiz zzS?{_$b{DQ-n(zN+t=SmQ6umi%k#oUFN9+E4o}*-t54M^Y7AzL&=@quj;{FxZ)r^GWEQ}{j0Y@UY&FAO=j?o8`h2KB6yp%UzAyzV_M zolTk3baptFm(FGf0Jj^O#o4sMyEt;LuRX$%U%P)Vql}JDnqN2^S@m2~@hEL@?ApW& z7caL-h9<9nT=2DWfFllG# zNN}XWPDZAXgPVcS&<@`WwZ~V2UQWOK?~W5rJ1c-$ZsF(wX*>yZw=prDi5 z`NOl$sxsnq{WvtmZ6>b{YvI%pQl}6XmlpHY86A%YYvKk+I*_E-&}5xFe3MVDa_xw_ zPOYuax+l_Viw@ymmmz61T#C^7qtlOU!T-LUp26tUF&$Q@o##{*ycyt3;7Z>=_;f_w z4rQH{Ee$U{2-0uDr!IZkR8Lb!W;z^+g`P=c^nhMnhB}<5r`xon^n(qGA?7?hWo%xb zRY!=+0gQ2y1|huAZ%srf{;+g2RaqYk+{zmU;TjIrQFzGnDTi`9PbG>t?|bO`mG%(0 zO(WvkoE(#dtFn7pJ0NBMHu@u?1hdTBK83HVmFwrh6Mj_gvF4vCAd zzo%yWWcO5d0GULFL2+z@Gf?y|Q)irH`NW3-OgxkWkxm2G>OARf+bc=6QQyIsk#Teh zZBTE!{nG(-@+B#061@(3YBz&wkGQ{me<$#y(}_IFy1Nca`GrTy)c&~?P=_e%`z^%v zW(4(yBh7(>I_#^*ZlK3>@<%C5yrg_Oy#4(Q+ti&^d9uq(kF&gz=W1V%^LSLYdN7T; zz_X#}{Yyi~_YV-l+keH-+cF$FPCNoXhik^OjDobr31vB}((fQX(kQxd0UtQhYmWCVyCmydw|Am*CL89^u33zX((6afgAW<)yYrkIKCcU2L2wTNvJ< z@vcM!%$|%>gcC5+@v$Q!Fj;ygq;X9al`hZv`O~TP#L8*=3=Zm-KeyPPy*kt8#$bLp z%sog?vQL~-BV`DWG4whrHuU(Aa-9ucn{2!HVM31GyC89UwoRVmu#PQY7~QmYuFcHO z<5(i76RI_Y=Xk#DZ24s&99NLBd+2A;a8gb%K7Mrza1Y44J%S^v@|eUpy2QZ!Cl}}2 z5)SL)ydyg}Tkam<5oZ-*0lRjX)MqvP4+F_|o+-9%-@Dyz-@MWGefey68>InGd8VV}h@;G)qa_pB+g2cJ z9bhSU8LG;!kyj6$Qk9-giO#9PbjEwgJJo}lgMlr>5ya_s<*8@0BqO6?aZ+8Qdw}Ac zYR9`4*TY4n>q9K>KA7;q()L&p!Wrbtr&`Cm!Z&_E;_8!E+K>JCPqb^-o}~eM?e~7;H`?$2{vWh^x9_x%T&6(pS6bHF zzVexG-fO_1v26hM&8@Ar?ibW>7Nhuq)sF?txCDZqiYBAKw9WYJF0izm84-EQsefOV z)G_xF5jTh)YKRI;v|7c1~~JycvE_9v|S5=d~<{ zSkgnC;Epb5J{H2G(0g2=rp?NL%O|9J_ELoR?97StC|}y|OKdJd_~;(aF?C75ee`AC zET*3NmN~`2Q_80Dv$t0x?Wf1^Fl9*Z=nBe>0_HHJ!<5?muWSzFEinWE_Bns@7#Sn-4)&%CGK@umbI1c7^0FH1{V*5GIcr$zYM4QOF}-)>J+Ltv+dQO@R`%F zB1Zm;)4^&>i{RmHHg@vCO z&=rR@a*FKNZU7$-N8*+=!Zgh5p~WMi%fR;vkq_xMxc*Cn^@#Vu?I#VNsO(3=FkBtZ ze%;&OLpsul8$35J_xX4a{OafH^_irHFOW}TKOCTO?R4>iGq6+P4SCZ+1$D1>M&8j; zRoAP}l`G47pckfRCf=}DggS&YgwFu{C#N42l!!5+*FD z*61PagU{?as;IEGIB&p5yYoexJ-^+LQxRghCKXso14<&aB38s90l`N(u@V#mr=u;O zkhc>*VZb};K(`mMo9tWNn>)vCXZxgGdH&`0#MLJUBU3WPNxT032N=a|@<1fYnwlQZ zwjqv2p1XJn#WP8PRc=?dhF)(JOs?vYcdi+9KfA-D-L^P0SMbt66@>6RLgpGi+gC?9 zRGo2$&pmkG9aj~Sp$oESh21jjIgipSnsj=Xw0^hWB_`reW#QDYNLFb~(pk8F=T1%Y z4jcg)TMelKH=Ph%xO536HilEXO($a+TphI|oU;S)cI)Q#_R;n0an|fqY;JF+ZRT_D zT`GyNF1j41GYA40EDC@S@!``$@TO8qWZL4?^ z=V_xlKwcW)%}{N(-8JH2hKyu$7*uLHtky4HO)p%+;4%ZJ`m8|uDCZD}PA6sZ+?Uk+ zz==2wU7=;<1}CX_SDr^UNbB}0IsrO8N9ZBVuUoNYk6mc4+}4^n9SWC6SjIj)T{BLO zj+I=N40Ra|tQ@wh$ICGFw9d3>a7`IQ*B(8u`b>E$>G*g^+5vBe&xelCO$Eo{Irjme z4yU5Cjn{)XaEKo14pet8QeNsZzaW{9II`FvM*~Tc6y5lH^y?nX*E?u|ga7$FW$5N} z4PNCl^m2yF>&~zt`~V!z2BsaRg&4ddw04{R;zms*_k9 z3(xu$(c=VpQ;hlnfbb5%`VH!1a)URQA`DCipSt|@Gz zlNsjUN68yT-7}R2j!#-Q!j=)DDe9oEnZq_QKhkE-Otkq6lWpb#%s#V$!oiUl*#Smh z@*>?nNZ6Z1NMJI`o5YLv1*&P+rOqsYyoEN6Ao$6>(>;W77pDlAW{#*+rL#*Jl;bu? ze%f+vXTKdFtcQD!_R6G`t3ihz8rl=OsTwAyo}JE+OtrBwS288{GEF};ZaPKsx{JV1 z(1Q2ZsN-q9{@j+;gdy3ga-X-oM}ObNG2og-M6T@6kK5<%=^e6*1^g^>&q`Spu%35TzU?CV!T& z8mFI=JSaEcrnfVf-4x)UKKdtoqRDI1cUq)ujW6dIV%j2};)H21H9+7&{_#*Alv&fn z;M4T_x=hufvzk#tM+Pa+{YBlYwbR7WN!NT`x^y{py#D$Z+OyBU6jqL}Hm$_h{SN+KNNyzNq$ibzI#}$|*e+y&&lno;!CA2YDf#1L5rD z>4;1BdaJ+IH1~2;bUMG{SXxZCsK9){F|Tyts1pMH4P8D=X76|q7HF1 z+m5}X4%xLMqp9SlZLXbmTctRt)ce5k2))G@rSMOuStIPdf*aZ=&%n?necku`qA@ljf07a$OaAX}OQ)^;y+dbs=rRnLJ{sGAblJhjFI&TJP&v-7Egdm-s;# z&MWQ>DVOM4eo=Cm-CHQiyS^L1qiwQm><>!s`q;0kd#r zWQ=o;L7eI8Ty+N*bPh8MBt8fEm3fySs@LQJ@ohaL%IBoBGRiNugmXr@HCzPsxH6jt z59sYBu5IkLdQ_CE%bn$LP)s<|W^iI%d09?clQ1;q-1*A0!Rvk=e*Wk&oaWJ^^X3n9 z_@lj#efB*L+wfNn!dWi%9w56ZrNh*4f!_So5_#W!S(ZWt`oQKKy!L0_(LoltW?!#A@4Dhz|BpFk?+ zr^ec)mAUrvbC=ssf93V|mCwK2o_@l$mlRGux2KuF(VCoG!I@jY33j_AjDasfwFB;V zIq#>}lnEZ{u@?zHXIee%c#FLDaBP3Q>(Ly5z#|SFf%)Dl>(%`bxX}#1-;d-e^X5Z(P4V=utb` z$zXjjfG#}L@doSm5u-CexCOZ}Pz z8K^4`j~+_-K$ihCtKh_IXI?|klhG>94)6Qfz6+NwW=dEda6P1XqDj08FKzKU%7uK~C$VP}V2C37s%x21@Hl0`GHw4kki#~6Sf;qP(@{7#U#bl((kr8BK}zwI%Le-FhV9S*iF4P{ht}L@q-=n=jAVlg zM{UfbfzPmy&&4wr87ZZ1+fy)vHZ)KPwLt`YBNX9i**#br}u%Z(m%MSTw$s=(JQ?GncwSVd-(6WLY4j9&(hXG zD7e0VC_WV%LiRB9visR`AC`v>MYqW7!(kYn4o7f8zKq6^Pnt<1<1_jqO^5Ogmyt9a zk87*?I^dXwvh5(-mNWvIkf|`oKhJg8R$=HdB<4>W6?v8+jPU$@4oh*H*~dK_J_1v! z(h|UPI;+4XYN~CrEjRob#8bC5{oYQGvo-EX>_CUhmm+%)wxXQN3ssr5Bdv~K&Cb~Q zqCR<+@}0>sUino=D9fJvQScP4x-Agz%220$r>U|_v85Bq<5`*ANB8z`^qbaA`?b4U zeP8N0uP2!eQ$G6$Z#t!<&xk5<%5phO%82r(&Zd3pVe3XNMVk82d?)Ceyuh0QIM0>d zvb+B4hv}1NaBb-L{y{^>*(W;WH~2Ka$36c($6qCwPnz{>gKakSXSQD+@j7;EfERHl z52z2p9;hzcDjz%eWmB}NJ;;xymzOQO20dy}qJs9pGPM~Gd2MWAdh!jGs)ak^siV5% zH+7vR)^QxC0SXdyl2kJC0+nA{S!gdmbG7~0mpnE zmIh4DVW7ty_TRGS_i%7fj$<@frxpFy#%A3Cz-@^%U^qKrTu$Q9FV>tQ z)Cjg&04|2lX~@E`>T`-o?VO&9KI}6&T1(h+u+#{ri7_vIGNV+yYljxPJ?+(ukeTA zxz=g$D^m+A7t5h=YKq`zH?2p+-?@9c7R8fC=he|JjlN~4ZNWFhB}!V zttvbfn=p8Ec*0lwI!!#6vMXg2{vRBv3;qa&Q@7x$)NG21(R3w-8&};B-`#rMMLPJiRaL&%n zwijP~slD{7FH^Pl?ptrRH{X1-{r>O%UVH!j_cJ;6 zaEF78*bEeqyd*7zv2X0}h^qI(W*OOBe0jNDxpF1tIN~i0UH>W_bUf{3xW36Z?!j1Q z0mQR>C_b*B3>w#i@b@%5-s|CZ zxoFZ3R@yyui1S{DM~}}v4Rkw1QV_>~>;OWMwT2y#q% zPMX2NzdD=0XlKYMka!+kyH@fO|4f_e2iM>Cpzgp`ut?jyKy_U3$h-1H0t`{6u^reRL$8fT|-KU>I^vzh?~ zogSYw^!9r6yxj))Y`E=)KH#EXCQX7R(p86O0)Eqei!;lpmv41S)xR~u{?K3O4s4~Z zcOF9LK@c7f<2;WoOisOV40AYzJ^}%E_Amkmetqh+OMi(e+#9>_}VcN z?hyjT;kHgL;6FJ*xw*BFUbx%aOwhy2`Ls<=fLMBsESnph0snRB;zg-pgVl9?_RPvK;Y%T z(K(V;kGcqGpEBE7aR!2cvfw!cl;{#WPLTqJplWt@_m11Wwf(lVbh$nG@+)oS>^X2} zd1LMU_uh$dB|{d;>*V@!)tL(y+v(UON(CHPzQ}zf6yptU20?r)l;id|$$Nqz2R7oS zXXo2Iy>OR(=)COi9N>7kxEa@#?LkpXmptQKqjRMU%@d_gJ?TN}0LIDyCHK-*yt!mVN~$1rXrOLz z>T@00G?*h~;!5aU#~5P-j=ECO0kV^$@hjTZwKU8@)e-Q>j>~jZ5a^0CrJgvVz$eXiNuzw!3m4W*09j5uITC-M!OKW%DLvr`4>$rto2)O!*)~dx ztdFaa-OkVEkuUs?wMH{Wei|M}=Sa|<^{qJ1!mDw$UJspD>j-Zn?{bcZKGuP_<=Q%O zh-c0Q`9pl0brAJ{cPf4HV8!&axk?suWjbo}Q>&?s;mKQ-}f**ItZA& zA1?RNYhfGQpd%gSD>%93T-V~-V42mXiWi<}uK^wmKBb1>Hl6=LUBltgIOR7>Fb0+% z5e!^$R(U3b!{tA$dl0xc&O>=OgLY}~@Dm>3YtUJK+|!RAgC95UE~4R201@sZ4fX

dQ_k)M>q+bI?!h%@Ylu$e5FBLE~5 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

v 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 Ah5!Hn literal 0 HcmV?d00001 diff --git a/bsp/phytium/libraries/standalone/doc/fig/usb_disk.png b/bsp/phytium/libraries/standalone/doc/fig/usb_disk.png new file mode 100644 index 0000000000000000000000000000000000000000..63a0fa9459dfbd70a01ed74e27b17190039e60a4 GIT binary patch literal 6645 zcmeHMcT|(vwhxL(Km?@<2nMA|lPDrZf`APIs7Oa@1W_P#5(5Mg2o4HSL?%))qf(?J z4ox6}U=j%+P0&!KN$({Eaub}ncf2#}m9^em>;3W8`jYdtv(N7PclLMhlErxeK1n_R z03dMjg2@#CU}#O^ z1^XZXVDCH5kBbP;g#iEue!6IK<|@K@HpBeU^vNgZf~<8A(+ho)V|{wLxNJBu^HwH* zuH@A)OvbfYdVuw5%yYdOuKB1IexcE(F?n87_v{USi^hA3Q6j5hvJ3J@E?W{po5k3 zM8pQ;qR+A4-GfU8;xMV$d+c`*U`1iDpaw{I-@e5~n1upN##su?wPtejzV1!{>7vK; zOuX-#vq0Q#+Y70kqpX#c-Hq3vJG~3a6irNK%zt>CLmm|5jjwph(_!be<(d%R`_$W~ zYq`v~LJ71y#5cKgg2v$DTD0jjl$@r>`s~~1c>KYG+mYq7V*Mgu)@Cz{2TfaLH4s?L z_2PcW7R_wE0#68rY;L;ryKK>e*4H5D`N)lVLI`Vh#Bxq^q3%B-DG!rz0$s~gKtm24 z8n`KW!6SoqS540SR(9#-wzl&AXWgLVyC`a)We9pB0ac(i*xJ_Lxm<?qn%BITPZ3pnmb45cXKy7nsY>_8M1|Y_PcO5LP*Tv9Q+%|CNZgBmc@Lh zQ0w8Xk;9CAbnJkUCz?iMo^;MM%8|I6QZX+f+C&Kd5_ z+LX2bQB(nz#=d=0+W*onVRMaYZWBup;=@Eq(1X9tP*bf~J2I=AOISXluV77l*BzAQ zVRA)j9MiS3bW9p~{xGd}EM>lq;g?JuRG)u0Dx_4c4)OL!-U+#4XaTcnj^x zP&&Lx*6c?vvRD=I@xE#A&z*))LlgY?aE_acIrx4L^X!Uh2KH2e-P9#o@Dz13Axw9= zyLClu{WbkS!`Df0?0cWilpjs6EscUrn=Fd^2}%eL@r(Rj2H*XL6>cXM~0Ic(_VwDD)y~ob&XBZ z%}DG+zw-7guO;HY-C0*aPa4;pEzYhnFll_U^1lAc_lOs#U1{Ih_mi!avn;^StT&*f z%kQ$$czyTT)=@#!aQEY$-GGn#L#0)Jb9{_N`iDF`PJ8E!&>CCi0=$knxZ7-2?3w^B z&Emj|Hf^1BR-nF1R{FCWBQ&M4zSQ%lFVayj6Vl1DYYq9z#e#reRLk1z53Fcht{9eTxiy?hAF7A%%Pw+$r~;m{pE-KwY)7k);mFzSPsPR=D$(#kgHmc#y6Vt*6a zpJDxea(3!tE)_mX$La|FvO5dhY+e_*^Q&OVlBQCi{fcgH!_}>dATco#a+si-Pizdnvk4JI zea?G9FGrN`*NOZTSm`_)d00CR8YUmK6-tvf8b7^o^TYH`zzv|@-X~wwZeJ%s?`Z0} zj0M{$^1IN<0@L zsV^0WEm=-bYnBQ_2aXaBaKal9^`vCP^=1FF7|PxJ1m<)mvx27ug)V?P0yoN<) zTA&Ih`_k`@H_o{vSCeo|H;o_UvWcM>Y)oRsqTTsIG({5Y!Bo%3zAA1STPvfcBxxgG z8P8?Lx6LDC8;;X1xWAe2yck-=-TeBga%xC!7xgvWHe5_Pa_6Sc4tGDNdM5_*q7>K| zArF)MsvP-2(M?-X(-tDHtd5TaXZYP1Yn+){F`8U&J)e*xV@h=Sg6{R38=5)!DE)kp zC|kL8_w~9uW^A)O_0+pc6AIIq!FJS}LVzf2)%Y6L+eStH?SnfO}WhgTt*m-9R@pssPPa_>6$jQt!p9`&28%c-ehjD& zaywLL_}MkP!ah!D!(Jg&N(SbLu5F7bQGzaj;++qG$EpKWb+QRb5vnC|>P7j;;#3+o7?g;&Sl3OfDN;rm6$njOR zKx?(89why4JG#YY`c#1rDg;|r$ioHT#oc0Kof7c38iBcpPwfKtTB&^jgaq1?%0Nx% zZTzeg5SP%SSGT=n6Zta|rCBhO+j9fyZYvxtrVb?larEBEQ_$XpU+2t1`?5sAM&mXd zFLd(D%ev=(Fh||SIQ!*q!RW8PmLVm-FIa@3lsHtC@Yy+#DdkOVXA|q;p|uyaUmWch zwYCA@byQ?!k#%?g!mSOB1&kxPYK1G`tbal1^d)A_WMFaq;-BjzxK|g0W&)VR3#9Fm ziyvEa=-5D?Q0-of7r-4x9{fX})1c$rCziz{=Qo~Iey&@oY8El{VjSo(@;oMu(tVO! ze3Blk)K>|sZCLACS5 z>N~yFkSIOR{Kb~ zF`}%bLJXXce}Ny=S(_LJS@!3e<{0OJlcU+^a*h7ff+KXvK${~y#@W)J>@REmQ(@mT zR36!7*fP(16&|?fh9^UH^Z~_q$Y<3w@w!pAK`1hC-PrR~Tu{#V=Is}|U2(OVNY3D8K3^LL>w(6?Zr_UfV{)UuI0W8m@vnoA1 zIkWjD=>0t1xcb+x&9$s1H@h1c+ngCWLp6YE0~*v>sHR zI8vamF*I$~j|A=vv@k{O_c0EwLAcKq#PMWUx!N2`x;3_TzKeEzOh0i>;AxPyx&tbW z_?C^jieu7Mek=0( z5=6l7fcedCL29avF1GE$n@$m(uh7bdaU*K!@p}8#?Da3Skb683>3iL%_lA*@4!5r2 zm6-LMqNY-6qy6wp4@j-%Cp|`c2<0K?{8S{hq_Hxg7PSr)2aV zkE|5v!4oYSWsjj4M}A>Vi5N3BN2uC7SGjfV*!%v2%O2`FrtYH#f4dOLQGbHk!pZwF(5qAOIrwuKg#`m7HcnMG-^Psn3-_X_u+5D2_K8iBQExG!Y@UsyJ@@!6a#(fA_aCaHx~wT zxkA1pYymdDBrjKK?;;H}+Z*NV#UY2%jk0ysoeR~M%##V+c-3~YX?sVEwCxNmF!f$I zGaSa7v3%^PoBPwz2x6KI*QMz9X2ligj{-LX3E~aco(X|>?zgLPgS1aTv){S3vc zeZ<{Fwu5PC?waSb()2+dd^O>eIrus$hB8^@DK89IYurXDe!RFT-yq;UkD(bx%S}%) zRr#w^v%0X>B8(#&VIHTQkGp7(p~SwGcxPmAnJW5Hwr-@!S4j=G`nua#|f?CCQr8O9bm1mPN zP(ak_(rqBbj$d8*%d(PIB{Qs+0fh=*QScajWJ0q^1dOCI)u-f&)0pyBM_AA&lnqiBXML7mk9F1T^|;ZJfuU?wxfFr`QPbZ8PgDhG3dH3& zPx#I)&?uTG_JTT#+<9_DFVCkeyZoEel$_fXRFChP&33PQu_ z%~H3Q;Rn-oGmHv!{j3GJ08W_g&0D`1cyYMvtn+CazcNghONl$mZAa=oJ?AwA)=T&o z4d+BRxj15ANjxJaf2u^~Do+ej=tMyrg&Ao<8gb;s8RzpU3LO;SM1u*Uu;o^cu_tU} z#68^aWX;~C^ba8qG+}wVn|zrl0K#e8Grybxv zpcLZ@N*vrPb5j0lloIA0m*}~EM&%19#l9zXg7hsx#vVsGPgMQJ3VEy5LtlbZ%;d*G zR;8;U{tX_wksEit)^q`YKH2RE{GQ^AGnfP(qY}j16QEx!jw(S;{f|T4|3wu2|D^w| z*YJN!A#>(ifOW$jkq{n$Q2WRsP>}jI*kE^B8c}8$Ah}j~82gZMI{o=LZ3K1UKe=Oe z=CGXHS7Ppj7j?S>^Bc$tZp?1>COy=_vHQ9}PPaEnF$fG=Uf2(2w}50V$6-d}!zps? zZf_&8Gp)jLiHy3kP|t}N)p~F>Wvwcm$yf^34V&=lUuW0DrD=tES@0m8>Reabw@Q>q%8_k;^jihH zX&t{&XK;yhzkVv%{^o>ful_aq+qLkyfxg-K1K_iwGUA01_d5uosvJIuAsBXdpm`8t zi^-KJA3t+7@p{9vf-N0lSx>(ftS;k?*MtG$i=q9h1QDyu(oHh_Z2!Y3zQ%}O2jU>|M21jBjElHaExSNg$CvGU4t?=-98L&9v=Mh}p%Bux21ehQ0 zJt*}4E1zrMd82WWw=y^7t@@TE*gFG=Uw0Bm;HWt^H*xttb?Z-*#g$oK(#fQq3++=B z#L2@2af@m`jBv`z4!0JM6CkVd9FN%M0#A;i@4mT3+H)sYFvg14X{#LZ(Ow{ZS4pgB zJ(6@Eo`uSflzsIGSAe|lL6Ww)nQ^IQGC_#_72sjNBJ8O~^*15WL5p>puSe`!?k3OR zcXfVAfqFF^qXmGF%qXPV-?(*fw(DyBOauy zT&=+8adoU5%CH|{~`g=%#GlO{KoitEs3@RmVI zuy#b%#W~g|;*AP%r`z{Avt%b#VSY_)C-ZC4zg)?+?bgX*1 znh)scP5|lX=#7|8(_;L044|}t-ur=$231n=LF^Zz+a zYexxVDI`<^1XV6~oHr}(GGK==HkKg!b&wi)NZeW*LoVllgdw2T!c8hPPgUyW4 znSqH_Z&7w|Js{AJ;GZuM^t8Mc;T*uhC?|T8@NkYRa5$sMR?fNvJ)pf{SR!!;DRPAp za&%M_4VSyEF@}OS4^rW9g?7R=pUA>Y;GN?F0t7Dru5Zw}B-*0cMQ|Xh;VYa+fX2tx zj< ztJoe&C3LyGBEVliuhtSd%hMOut^g3-cW8 zhfxjOz(GgO%Mf)d*DZPN!xY5!=8#0}?bB6=7n+ZPv7L{JG&|Z-_%@<|7MF70Jm1e1 zcXWnBZ-#LL|0l#U*bn$(dNixVWm?!_d8IRWmF3}G>jHYk24)_((BI68x2IjBO`pBkB@kw$NJg`E-GI?^l%EnJf~Lbj`Yw zK-6-q_g(ziC2FCLt`haJB&)};F%!QMdtgExXoU2n{&f$>3j8YgMBd*rB{cpuNJCfX z0LSksRR6?3p_d_GC)0>kMhJS`f;Ln7f8uK-!Q#eUs|zzr!e49RDxwHoo7K+)HKL68 zUVCsq0k*Q>j0KYGXj$m0UU36=U)>5)i1Mj%{**`Pw8D=lwR+5nP{dDAR*yn$gCP3M zWvANSQ8v@+yGWC=%JH|Q#cl)aTJrG5N8A3N8)Vqy?;Kl2;t+ARs^@!`=(sL{bGgJN;6!#_HqF?0{+@G{e6za? z*vzQ3JAs1&P=%=F>ekeDc@5X&`SL8?&zJ=jcuQrD829C!XzIzqi$ZugCjjv3qtX=Q zlbAFEj+c<#;ww=aE1pBxx_fn_?8lWn`~z7vG5d+5MhxU$z2k>ay#<25u6wOZEL(M5!$DL^j&Q2b z%=n1o*7k>S0#gq|KX5YgNkgT;C$t(*{+T~F*)X?xHwe@kQRAS&w<2fTWW4Fnyv;?GMNO>-6NQFbzrRbc>Jgp%YS}exnZO3po<#jA?*vxX$_+-Y zGr^t8b}J>*3Sc(kx;_n*<3z0a+rk%>Kvts7PbF&ulSp(ie@^CH4TOk8`S9p!g_}GN( zx`obnVZodzynAJ^*^+{YeC~4V5-8X0FjaCobFItIfrWIMECJIg(;C%z53#w1toKAE zeI$(y?(ei;?}VDp)-DkcTfW(YpC(`?s23spvxbj{T6aYY5ETJ&bFf1I`T|Ph(!6Rq z#f++S1N3u*%n&-3FAIK~G=AEa>@Oo^b2*? zIK#!-LVb-JpsI*yV^ZtzlHtnJ;^i+mbDNiU4>GD&5@+#2b-^=A4$DD$O9&! zMM!X<`Rpv?DMI9JirHg6K8!w+cl!D;)e%S=0J8V|FBg*U*s9!-k?5CJyz!_bysEx> z<2lhSBpBRnyG2n13{Y|QmYOUnR19JLUTnN<2aC!X+ifZR!Kf^?$;V3c&eXgP{N7V^ zkQCni-B8))tGddXZ#C(1f-k_oKss)VzZ7DdPAC-{>hd)2D_yXz2*&>j|J!wOTY*zM z)CL#F)+=PCCWoeyeSfXAR5hSy|N0?tcuAP9Su#u&NPn|x(&N+H`&{C@U*NDRK|^dU zN-J8dTe{OQiABbAM@)|^K089H=Bi5CuD*eR)t8VQGHpgg>w-qh*7^G?_3>5nH#=JS znldSOd42DDtnzneJ0xTNjzMdspyM(4{@`%t_QTc~7i(hhn$aV&{lsq#sluzKFbq9rT-4l8BTyhL@pVJYuI-=4M@S#Ikv?f3ISdR zuQ*^$jx;K#d|`Wx@}|(FfH~A8^UC0CVgQsj-b#aJiS@)xSB5XLV}acY4YH%~ezu;# z2vP#{_egE!*!oUYvCJNJTWM`2B~Mr_6~=zgqRw(z_>=BZ!Uow-M|sa24|2zt=?P`eJd+_ugz zn1)#^(iZ3UFA<;lIDo_RNzYnni_G!vAIc5f@L9D$YW(_i7p~yMb3&AqqmB-Fz;_W$ z%P>WE2|VWogXSlpvMx~iHzb+ZDzueutL0wRd?OV)2kZ>!UnoA>UBR#t6$=ee@Lto! za?nM^&IX7$bs14nid4!FZCy@tzKSH!tMs&{Y+J4^F3Kui1QYiZ?2avWY6k#sj+;EP zeM$Jr$YyHgclGNadUN8t;*!&W=K~qF`rYq|TQ@n)MO4W(l3oiw@a#TBA{0i!xA2to z9ue9Bv%H`&n=cQoyTCa1i)0d`8-_>)e&$WeKZZWTN0)gc)veG`S?*o)w0ZGnT-@8mSBXx5x$K;rn zqie`Z!s^QObuMm?9iBA8nO=`diU5iBR&EOh8TVFRyc3RlpBm#_ zE$1aR7?muiwp4cod|M~wmne9M8q+lgNgt3sJP*L7qLA>JVL(>xui;#*hKe{wHuy1u z6ZOe(LvL&Ci7XOL>nweAz~18caoffRL?Vpdoz%JiZn=E;vihCkVc^hgRMkF1WRj6% za%-d0Q}oGb59a&hLBbpYgP$NG)V58ANUpjq3u6g9YM7h?b-|bM;bnhGfe|qBkH7tu z&I>XM^3!FJ$znS}Gruh`Kn9Q}G>tY#taXPUznmt zboa#H{yf+dWS8KOM3(WzB4UIdENZ@ zKE}qso!BDc8`7aB1wNq8!afJ7Lxk9pNnE>}t>n43(xUT0TX8E_SGmJ4(sFKU2%H1H zy`okgeN}~&##kQTd`kW9EBmw8hqy$vQGx-zQd$NrrDheZGeyUZZkBUNNa|h^;^f_9 z6tO#6GcnwA9Cv=8{DbsldH1@#4NK;E@uG9Uh0>nEW?J&lMF&H){U0Ff#uk%EE`n8% zxnSYv8nH#9VYo;R;Guood%w9NNATO=BGIu!>K28#JH(@` z-3KpXRx&_e-%5a8eEWOje#&m%v$so|%tc=TtHF`Nd22Qy0yE776NB9kD%)NA1mXr6 z^z3m0CPb!RU1zdz4K7_IvDo;3!-~Tv{~K1E^mNUs`tMk=QW!)BkVfki({Oc&MFtdHsip=*p?k$s!3=tmxR2j<<|n9p?{}xhdScBET#2gSkf%;Q z<@Girl^3wu0ZH%bWXZZxxzg5ojW)28)t!}TOo7IQpiwy6kA$1PG(>%KDJE@!A$|}0 zsq5G2K(@t{m?L;<-V$ch4g6j&n({7b8Ca7D1Dpf914xoLyXxevAiRlVqeJM zxA?q9&zjuZJDP<%!rxMP{d|7cmF|kJg)dWHwE8!GX=TiQ7&2Mw%AeQU4ZKkQC_YK9 zM}8QjgP*p=x(f|ZI$Yiw9rzGc|IBb8S8ibR#_k2Ayt{z4wl)tqQ2$E4lmJS3sNG2e zLfVAhU6f@kg}yCj=xLNQ==U$S`#s-x&akoml)LoNZB-=$#*fWO^Lo?_GCH|SRkY*= z+{IJ3TADcXa6NJz@fv9%-4A?n^^oE;40yirYD&@@e3O4;b8E~a*@CGb4}#8Hzu7mh ze{_qh@U9^XX|Z@sfE3|r5pbWBy7F&8>th!pL^z_ZWu#Z$gZH_QyO)xm0u~C44W?>? zVZA=bK(_mtvB4eI)mzP|w;W7dEYl#+ulT}^ajb|IC;mLHP%q+LN#NUjW{gqCIm>r~ z21k3EgvF>b8JlKI#r4V%!as=d+G6o4{r?6r;uF`9Tit_ak%lP7Z~cUY>g}giJ409( z|Mq2@EAceY>TTS<3Ky~#KKXl(H#%*N2S6@omf7 zDE5B>jiX+Ep<1j_MVvYvYbNcJ%xg2ViDs3sUSqIRU9HMRb{NzmN?XWU46=Z2TRuqQmg1y(jm?07-i5E9z3U9^pgyi^_X zVrYT*K4_+*WEf;07P5+lUVJ^cH?y!Dk4Rre=Ef;fmvdU7+K2A~TuH%X|5CW|9#Y5* zHth)P4~c8n!A+J?)AyO7D!)K#*GmEpO4XzK8>Nd#vs`9P=8N9L7KKS-{v1X2W(!PU6~*J(GT8E zKkRu+7_wjf7ha@e)$IKdibxkno?Q8a1Nw6bz|P=XI`|?Rkoy1z=s+af zt9?ju(#@GwRd>btELc*s3ltj*qQOEaqHVO4UldUPM~)(Wb$?9odZ* zU55n}PdpRm;4@|D)3!!yJ$ZuQ8oQP$gQVeQ%ByS(h%qP({m-u)mC z=#0&>IvW%2b<$6K-JZw*$ir!4F3_l;)vK%$lMeRCRQSsL*tWu)z5zzoZTmk6&PTIb zajFc2QKJ=T9NAK>aP$S9=Ro>>WB1<6MafrrfP^b)wFurG;1vnQjxIF`>bZ*L2tGyc z*QN^Y*#Y}|>*>sA4I1>Gr6Qu7_g4C=k6+%fEsaOQ8ED6gC~I=cSng)MxV$h++s08% zZ|COF!itnMl#|UyPI^^nCaSI3;#tIhAnZUe7}$*?G_vCp*^I;Y)I9zur<)Mxa(n??lI@r8IIKYL zcxaBbMjbJ9unQOsblRw9CsU0G7W?HXm5#}%XGMrh|8Wy&9OcsZC19P0G83%|y2aT~ znz2DXTo#w=F;9;p8aZVzgE#5bXj@_bt8M@A_Rxwl`a3&N+FR|wG~Tdbsf#4I(EgkL_@ z5~z58-FQI%U_XYTEa%~$ZweK)RZlox9ouo%^FCU)^q}ra&FZS1P@VEN_eoafw=%uD z#t2@r-)|rd5AKyd_dCWg6LZ`)ouQ5xdo(b8|G)p-6A(#s;Khxc?0l z==v}%>j65g?3&KbG2+Zgy$MMAfVt6(5k(+GZuuOcHb93PctTY^MgvC%M%4rXIBAX#3=(n{%=oOI^-KCHt5zIZu?w(UGF__F5Co5QP#DE!l5h8Vkov|Jh5! z$Smg_AM9d{Z~HVmo!`J5cv6^)Dio7;K;@w7R5kqKMGq9Yug2NpNwN~bigBnOGSTXGRduq ziVOQ|sXNlBagb8NLv-&qOfZ;MT&U%hztl0E2kT!~mCi%&-(iImINH~d*7Bt)*QmMdT}S7YDcVos+s&u|g35*zacUD#eeK?7u~G_nGUN~- zejWBrT{n0H)>9^^yxw3_jxceP-YKf#rf*Q+u!{D5kUChAI(uXiS+>o{7KiMg_1qC1 z+yEW1Rh`qxCGNcWO!2QH2W>%|;0Fqm97ALKgq412swYWaNmx1-fpfhw-IoTv6^9$T);J`fTyZ%WSk8!&?k)IDNT%*cE6K(D#QH6Fl0?JFd zaz)p{#Bqv`VXv_FA%svFha}-rHd=S`#^CigRw;|sc*?MZWukB5#>jp%VsRPo~P z3wxi8Ewf3;TMFLSY5dU+eNi*tSe+B#k+1gtA4qzijB(k~i7Z=DJx$6;>E zekUDU$y!=8VZ^#umI4d#olphVrM^^t^89{_nbPo`53hP2JehkKR%dnAK;;|&yPW^y zBA;!3<&bNKj0CpwUv^sDSDvLP^8TS#=S1Vqc%sM$Gf$%iw;a-Jb!-RVAM4-lgOshT zH{>OoCX00TZoPCUyJBi!GpZ^&S4?tt_3due-!z;zUKIin91EeR$&<0Niy(=R(mp5G z)!A=xv!$-RuB0DmR5jVlV9NeTuv!*Z0Oa*YZ)f>HiTuHL9qv208%eUIwYJC1-jMXh zG%v}En@kHKKQYrivQ^2w+=u3!*L3dF(uS~ zR^(S*QM)~3U+TqmmWRX;nMvUl>`KCjc!;rNuti(O-dq7F75-rfo8VXxqEA-&w$y-P z@+T$i5zbgo<*g}jQ9Jj0V9P(T1~WRVJyRlaV_+_z`Xv;ZyI*ox*4Z+BHCf~CWdBVZ zxqvI;AaI~FxV+PnHy{7FElaHBV2kR&DTQKk%)V~`&kV2M1qU3dq#`Y@4v_`aOi*^m zu-n*k;^0Yep}O^i+SC)-vk7xNLHLTDGLrE!TrB4R@>JM~iLjKC{b$~SxG1^K0wfPn zM$~p2{!oFS@lGG)bJJIy*2N5uO$NAH+XRqLh%Hb+$5B`dMffWUI&vgtxiJH@E?Qw{GCqmlUO9RnYhyf?``chP`i_>89Sk595(no){y{B zA7QZF?zTPJ>N=X?SeJZ=Lu)6DHG6!$2H^TFFFxrUX5qh6a;m_X;cAN1edNdccy?b* z*hTiY--&`=l29z{#S=c1Wkr#V@n?!8RB8OA_7*PuO~=V$a^(8=Op{^NPf&Jt!uwlt zMDI(xV{a%2KH<%9z&I?Mf{lkbGXOBjFB&d*hiFIaMDpcqBQJoe3t$lW@ElTCpS2obaE7 zCDvXeRbXon*JkFe!_}jmLq%Qov)4auT;A-$xE&q&*B{XmTeDsUKldK2e^70QTPpK_ z0Fo3SGH2g5Z~0W>5)ytbDD+J8{iQe<>S&uymZM+q_ryL~lx2^vkD=lR!oGgyB-GI+FR z&g>g*9G%stSFm;&GMHm1Hs1G1Nu+W6rOGRdz}33%B`Z3r+98hSu_F###c}x7KJS?{TaIrW%_u0P})9jXp5K4{%lgX?D^X7%NC@T z%>aNKO-F*%_a~gu2lMkzYM~aX4s1Cmt-nQ7YjPeRe1_7eAfk*Mp0;tkOUiX&kjNKE1)z3* zbrx=j*#$0iKh!)~eqm3ut^6UF<<_7>B+uKfl>&wA`1aC{@XPWeWH&3fyC~?vg}+5< zB_nK$OxFe!o?cKDYK?MZSG#sYZ41r#-j%h9ZjZLb_d#S{!2g7cKLH5 zVpdfuEUv-->!hrgUxhn0=^}y5(X@YU8WEgL38KNW)LBy^ChTF2jco{$1(9})v^KRT z-012Vl#N*eLmx8Oi%_s0?5x|WdykB61Alfd3`(%7iB5^S+gndwh3i}dyZ2U8$nsN7 za1Ydsf?C3wR7m0$RDM&@IfI7-=rg5ad^OP9lkd&p#%*9ey|8#RjS;>gjmUv4`TV>F zz=gawLw3KANDlrB;99!G2z&w?*oWBnF1gV5w01@xRoc{4?Xze*fSr7d4%b*IsH*2u z&3oxUhUQ?{417# zJ}5&u`dY0pWR|))P|P0Mfs6d_ep4>#c|O+TK`HK7*$3T#sh!P38rXizbNMV}M_%62 zlm_h`eSSTTtE4S2k5d$ByP~$8*B9!?dfTVBzHT4%!A&jil2Z?qLcXC|vJm4}O03GP z(VZ#xxQZHeV87qMq+H`3u;-?!S-8g=XGia3G4rGejwV#vEa+svTt~XiC&QKkq+oio zV_5E@F=qXYy_od~8WUG*bGK)1lJ0%I0o(Nv=Rg80*@kt9RnTVWU7p-3=%%@{y?(Z^ z4VNGG`oAEB$&BKRS5668669_-D1JE(=tfOliaC0aaYT3z$GDhha|r5i4)^aDxqvBY zJvO_M1zS6ou@eE|7N|0u?I_y{EPL@YNhh4ts3hS)S|A$#U7wKrSov#_7CWR2c+wI` zRs)T`S9q@qB=?6kmwOuU@pQa%r;Bytvy0$&Lk$9^sn$oUx)UDL%q{;wjqu5X zvXZ@D+YGH3z>}3R;4vps>RJpA1#C9Z@fCg z^Dj83sUPS17tQ^6IZ*x&n#;HG^3-@w#ROg9GDVQqbkfXLj;>#6Wx2j88B0uPjC==P zp%KQ(fBD84hx>jF#tF-ACwd;57pAqA25X~D2pB)P9yL|9%Up+CO_+YC>W1u(0Y2pw zm^&Wr2cZ>-@b|J{&Lr~Uf`}vLz?u`degLzk0lDFezmzpUR>2sfX3ds9+x@W_G7@c^ zeMMt89CY|AdTa(qDlvn*s-!3L7jv7zQ*YQlT{q0Jg3nU3Z>&bORfTO4`~4E0I$0mC z3##3%T%|9Amy#GgovMZwUB)RU)9&{(H&s8ZKBag08Iww}qP#AIBVV_y+0#aR7^Prh z1c4d>l^;1|TIIo67B!=W;f2E{EE6*q;LDU-74;vmY9T-FAuE5>Q+>xZ4el4uFrFTl zdL3PZlyei`V%F2@#))pg7HQujk(Mqgj-R88(=bE(Tig_*7vms;Mz$|t z3d8Z9b2s53AnAMP;-pI>>9NdT##OCPTVC{eFVHCr@7-XXjo7^K^(<}X`ij7uf6=*l zthuXwdcW&TS0H~XgWaHeJMs(8C_`n|p3J6{+zJ7GDv!lpZ5XOdwSp(NW*MBwJMe5< zkoyXzmf(8yUQRTjys6jQRl$526e}k3&3sUBkS*VTP+X$8{AO0o?W_BbtIbi6nbKDk%sFY z2N|Gvqlak1%uNBbc|xFijm1Hz&dvjoh@4Ah1-d?uXnWG{n&y36erdzvg}k>|U4Qt@_YYc5dWjfUFTT-|{FCj~0u%DKW7pOrK z*0JuHYHPKnZcjGMrw;u_@hqbZZ6-DfAfv2LC+B#SxdIJPAj-lvb{#Ug!4gXxK-7ck zVuxCTsCC_iZfPsR@@h{fSEZ*4;M$Ew$sS$yr21WLas#rDsfX~KS&9C8k4dp z4h8*VUgXY$4rVWO+>mUN&-37n@bchQ*lYpnQR}ndNtn~`2y&fst;9OA5Gw!U^RDnT zDAKzWy@VQGl60R0)v=QIXIzxr1YY41I@UiJWhuxrAjr(~ZlZhzk6pC@kGCmaFoRY$r?e z^hWxEmSa1gLHv+C_=y2}??)R9ugTiG?WY`dkO&)P?a*7lDqwU5?_@_<{pY6irir4Y z=X6ENA8y35cg0nAOETkGlloWJ4=;<8B0q{=%loqU9@;@U-!3uHu!b5s%}CtyS0w+E z*t3g2Qw!IL!1c2j9~ytMaSfxO18+1N`!J2)`dXZGt^`ujShBj^TC|4zysl+s2UBvR zUL~N9e49=>E+Xj&1xql|t%-mU(1{vym|Hg}%^6ek&V_5IN64DsIV622%+tb&F_muZ zY#$4;h?SX}^MpFx$I%~aM!UDUIDq}(kG~k86r&%UPG$U?WbwqmQF%YRW-r%Eb}Kc7 z=QbXW1E8;>p?@XbZI>-Mfet$Ic5b)3`&WbR9X$^SkN4Yhyri7_+Nt6g%j=718iXvo zJEaNW)F|HcSKfAaP{Wn`i>^E!-bye2m->6yTk~#?|qCaS(6QV2gPE#&6Y4w=Zd zzI9EI)fh3FS|cLb@%ML50S@3Oxmn(hi7m*VseDF&)%b8!T5InGfR>xiIxJhHGhoE7 zJfrJILc|U>8NzweERyNO{>o-OE{7ww zjD=MRj2A(7(RU<|8{3cz0Pe8W)4JlQAay)&mbsdk3!)qEbTZk!8@bgqnMQ>VFZ%E4u$rqWJX3=fp|+*C~hG2%-~>QQBP90#BwujjUJFbW>4Ba(_}r58J#Qsc_HndktFAS1M19Uv}Wda zDby*?>Tf-~cngv44t=EDc2`>9@dB$-rR%Jj)u_X)lV>Pn%SfA}n5!?V}XZYBQ{La#ZJr0W{)v)4JBlY~4EjB+Q2C+c*b_Y7-%J#Y(bcO$6> zlA<*lXkhcrfxG8e*Al`RBMt1V+iLXa zX3>OLskC`=Sfha}{}l+gQRz_yg71?ItppFXcQkp+x35CXEs?pt(K;Pc@cM)-h+SkW za%hgV^jj2_w6*_a)#Sr@F7ufKg7^t=&{KdJuF$y7;lgWAXsl+ANJQ$vCAb^)p-_F| zY98vfZp`7S57(#0j`^gluq~WeF5;AmmCAf@t3*VW$74N7X?dlq>SNwh9DPPgDxQ85 zPbTI+?ghIShs?J*`-&{uoGqYtCopu zAI>6CH(CXBePJBH-}v_!hab`0$IYP~iC8o5J%1kDJTi4W=B?-uX*_cfvSe9c*5Bty zmuTJ~mIuf>`jz5gz4ujRaKly06aC+c;*oV;k740f0hEp-R(B?v1Z$>qK87A(#{d|f z?Z;rTTf-Mf-GM$h>i2+=gV_+8IPs#pBzR6NN8(~mc+RSQjQ`0arWXH+Vy=e`3$7v& z39lhWtM$-7Gvu9O1aS32*`h^M z$NV(4t-u0S33qI|9zo7RHDY?Od3`n|anv zFve?7mc=3yh!B=q5|uj#SC5mJt}TO=2Nk$zD@Pz^h1FeC9rYo(M;%*u+i}_Ndv6Ev z+iQ$%3-KZm2tfs7^pSpyGUNg;F?Fo{;<|x5kSr(HaYtqh?H}8DsIrMR!8;p>lO%vo zEe!B!j>`!WV^*+?WX#e^J_IE=>-&J0V{+1Zr>nT z#LKRm7q!?EtKB0VoQv1=_aqUKoM(8dRu=TQk zC>wFKRuZ$_PC->E&hA{ZO}O zI{_IuJY?rnz7^;OnvnYTWpZ_IwZS!t=7@+|bt*_`^DWjp++_9@u;BYMCI{6WZq%vT zlOYD{95N`!q2I$zNU@-c_Xy0FZpPIo7`?6T;8RLz!7XyAkX|al*b*w2tzkEo_SnDX zP;5r2z^kM`8HugV(!eV?$=*%@{-@kS3X>U+8UUfj=YYWGr}F2*ObpKq^3^fita543 z?1G2iwDpxpYC*`~I1Jo>g6A=ssxe=f{aKPi$z~FnjT6cg8>}k#3*SyI*hCNLMQ!`9 zB6)z!LA`hVUVj-$hz1jFG?1gW`Z;l_UN`j*%>&fyN|vvOZFw^_2|dlAWK~|~Z}AA6 z&aV(|f`0J}CSz%$?m&fiP@f;Vs3)>{^2&H8ZCsBi4ZrPAu!)?WdSe`tB}SFq7<^+o z8?2#Iq}TNYBXrW5=zT~4b}M-KseCuuD<_(-O=2tItqX?j3uwvVkhYU~uF(!3loO@R zp9m`9g~Jtmm4_?7-ns{gX)5UVlR3+0E1cR?-{V5<8aYrx&%mCcP4`w`2M72m&013% z+7BnnJ5dh8v>Bz~c3IoOr+Xt_mR%OA-td%Xi0+~%2yhowSmxB(JY^VG*+dhR3f@+v zBWew>4QV=Y%ug0HHI5sS*43m}A9t!J3f%GMc(k~z6rWV4nz84>KFX~wZoiepRtO4%ND~suyE52U-4bJ-vTl&0 z-q=bZZL-X3t`hcrBZ<$r$X^zy#AMK-VYr(6^w@bIJy5%mOK5tH<#=lJlUV6zvQO^3sk zgo{7_Af$wCDA@^<_p0B-zkjUr%=GB-4U-nPTZ4e{HKxjI@Osd~U>PdQ$QXUFHv&`H7+4xbNn(BWU^TFoYyYGEn9vXKaOJJ4|UMxF{+gcI=8!>DFTo9nDRP?=| zBmb3?xSJ;N7eC%AvMgF0v-uzjj=*~ZS0S3cQ;c%K!Ux0n5-mieIm#_luA}wJy1DFf z(vr?(h7Ud6`x7Dy;b|hB9=sEJ`&rNY>?1l#vga@PPxPFpp9!mGFO9_&=Bk6^XfvgX4cfWZ{+z zTBOVGei#x(S9ce+3|?VF1Xi>_SE83TsG;I?zt6u!C|!CAND9~YTz*lbkQI9=NL!i< z!*N*a{c*=@o1ocyN3ly@fAFr6SChhm@zR3w@ZRbuvaJsPoP6O>IhiGePSj%N4sMYBYKljMw1w#&*de|&c{lErq+g$h{u+nh+8 zGgN6Xz|a3uf59Jl7)W1M{6;k3a3Jrt^iop3eo8zY8_F~9MNTVE0cY#?~s zE3veRCDBaz*4W>zRgEwOv->G}Qk4eckV11A!fHz36frNTY+ zhm^Cn#B|zBVO}|jDVVXkAQ7dbIz%L?7 zZV#;B#s|x!kVs{<@gj+FA!o0L!39H~-olAbG!n#n$b`k2y@mp*iK}%bUobCcZjiMU z57)NV%9kMn74c+iss|~-0%SxTyHC6UvK+G`|Jn)Vff*MY_+@UDv=8K9hn6&YZdFp> zk<3&=gBbwc+(Ym0qhRg%xz>Y1>suf?UW#Fo=8nD}FK9>rP>~H|9!^ppuQg3%{H%7R z;(Wk*@pGkv#}EBHsT?+r2g!Q_q&kjow}SvKG8wMi!Q@I2Nw z-!+|OgR5t3H}!J$9p?bt_hOwS6LN1My*s^TuU=Zlv-a>WQSm_>-(J=-a}h7=!(-Id zVv*vn9XSN`k94tDiPE7sG{}9e zkuirckZ#zY#p|(&)bo^sH&r0_kfp1JsJc&N!xt!A0suxMQ8Uy3qQ%f9wB zvjnv&&_GOpn}WXk`ehP#G!4dRKt5o$Y;Smlnp`+2Ze}ytQZ3wFz4p4FYc&^UlIqKN z^;gDz41Rs`=LU-Az4tSSEQoD}UNHLQ`Fpsni||MNIg8re8@o7+2gE}@SSz+SY$(m| ze(lxdmw(=g4jF0Y?Z(weOU%uF!ZJl?t|xg)QkN(|ZRNd;C1R@!+0xlGBWdeLbG{*F zS=LU)sJ#~3gFS0gDcl1XUM}bki*hEAB6zHe#vSY0@97XMR-FKJCLuR*lXKSwFcDVqQR*&F|;J%ZF0@MMtF4s*HnI{qI1`G-Cui;@Gq;4 z^f=}r)u!+2|F~?Wq?xW=={l(ozbeA1|Q*kk!zOe672!MCgft_N(vs2 zl??7Ll%!LnhnD*wzkkw1AgpT_K@t|#T%jt77D_CM^c4o&i7Rt_tBfKG&W#a@ZI$Qf z5TJuq+MRV`1KjOb4K&vB%V;2uA_*_-iA_Xd2BBfv z1`;4cBN$ZA+~*g~G&Iyv$T{R6W+IyR_hsC=b|q1M=7#_E04LJ*=(Nu?tv=1252gLr z0<$CILxJ?EuPq1k4Ug{&uqF)b?FytDaTagp#fQjKlKzueT@<{K{cLSM_F!3ZeQ-1U z5mZWA{`-?)vp5NLcRnJ>11W4~xL_OeDg2^YQlk>{JQ^UhC^PJK`W zq&-52br2iq@a=0k{CF?5qWz6R1f3lGQ_MePqqB? zsliQd^y@G1=vxpOaPuzfq=jae8TptkS+u3mdPnDlX|$e2JLxi9u9?uNGx+z9H+@oh3idKw$#dGkF$E*4-z{sOun zM2!zj5=`lE(00(3=4;==`duy*nY!yd?&~nPFg+phdLx}<|Ut{mC(7O}PeD4^&` ze1s{*RXB=iINpR0{77%3g-n;5QWQlK`=EYo>@&Q`BaZxOF1dD~7+l|P2%@w^)umZm zoa77GJ7%P^qK+9K#hWz7=ks62=LIL5gO+%tgTU;aEw70WRzDdz@Twum6k{Fqh%m$z zn}@r&cGlC<%zkoew`BEep_TZ(JPKX@*%>aHRlk*){*k&0{#)YuUtyb;E`Q1}OmKp0 zH(3X@G?IR`=<`eR{ANjgzq9Z}$6hj-CcQmHQ~nG6>|8GTt!ESteTVn}yQqL?_#eGo zdpwi-A9qPY)NmwsGIQ&&lxAsEb4`=zbR)M^azDs0)(M&ASboUlmc&j)$o)>1DVNFR zNaQ|p9mb5=_IuXp_t*LVw||~Lp4apJexL8>^L+Pte?ITeTi~V?j%c)oqBPOOUQYBr zZEBvG%o?jZ(ik@Om(102fJ{uTOY@`Xr!5C98&PVP+H?V!qA`2?YV&&@*&sfim$I)k zI&abQ3+Djx9S$fvRi4{npI3sW3*n<(cnqV)HI@%9o#1H?m*$4vY=+q@Wm2*6$D4Oq zJ(Q32LOrt3;+V^!M&8)!U5PJ#Y0KqFWkZBddu;doxp3z^Hd3!rd&F+LmgielyqR0K zKlBDEQfnz-(W)@H1z3oh04P}Dh0J$^t)az(kkL#T?a6LYZ5rq3(uNLU<|>Qc0EuA` z<|*tKjKzdEa`~8#WtNH~s~+}EX60ANFlPF0(Yk@5H1wMJ>IrGdPqPke^k#VhFQuQv zwovY_P;I!PJopT3h2SbYtIdC6*L$G(?YN`r^zedc;ICt{4AqxEAK3RuZ9 zc=zzb*dr!6ia7Z+?9qezl%evWP+al}&~&O#StT%9CFj zUaLJh_W@haJVkSDd7E+=a{8`nbr&%7t?l`U701_Hc?cm9eD(gY>yZ6}J_ln#ft!bM z#QuX?ORlYd;B2@hwEcZ2uKRsXVRwmYQ<9!#E1EoOfc(+HzUK_7DKLs%KG0JZbhp^= zbI#6CWJ?GRj`%>c3Lc)k@Wo7@Clm&P`g0Pe_KvPoSl}px&Xvc+AfC=k#Oo110wS>F+@(EdIlX!z%0k1&AV}!5julh}7bNq-01%pGD zsP0ap^(cr4a=1gwd#;G{ZJo4=_$)Suj?)mjomCM^xaDMq8qHYm+>zK?;hO8xyb`Eh z>^D2DfZOrm;_v7rsRwg=-WUozP{0u%w>H1%zPw)`N51I2fWUqLSqL3vGo-m2(~`hR zFi{JDHOUe#QF{g35qb1)g0aDXDt)*mAIO8(z;pFI0Nospvg@A#CW;YG@B9>ePZmZ@ zrZ!=`Op34HwW^dGYq~?raVt5WR~;0#k6&A8P{`HtU=3Iulmw#h1CHe0u!rwF-K`4g z!EJ-l$(q*W;Eln+>xZwN3J;FGa}at`x2=(%U3fs65G17B&i)gk@ikCRy;3`aJ5u^4 z(rH6wX7^m}`n`*dmt?c*;g-criu{_Sdf|nbzKDpsB~Gs5wywRlSoBpYYMF zv!wCS*hQ4C$6hIac@^cY^bMa}#EZX_zo=m*z91+Ghr>;Jva&bsf^FOfGGzU|!H*VV zKG@iX$v{z<+r>>4oQJ|1w_kG$N8nGxt4slFAkt;$(v zw!gkM`qr5!Bjt6704I8bWZEt}YZcJ(@{pzu&o5OjY>^)@Pz#m;umU~x-6AG)WJW;# z@cPI}nrbHs<%)k74w@b)*7InnQnxflGbQ}N9udo;{A1g`^%YQCI8pZdJGq?f8M&Lx zK)X0n^Z6Yk6#FSTVmNDecEbx@1}V|JJb5Huu~U(JW{h!0A2SgopL=*P17Kh3d0bMy z_MTj9CdjwHsR&^I7s8sNP7cU(_b)!{R*#rmQ;8UGdf%x<9bUD{vCCUeHdhnPVT|uN zB$E{&Cb3y))_ccf@@c**I>hXWw(m^fFyb8BLZRLw(GmNDn~D}!`KJv;AW-SwMXr9s zY7#BnMlq;AS}rPtEoWEAQ)ynlyrLIb#s91O6G*^@JKm1_Ixz27G&s3C>r(kDWMsfZ zrnx>S{p8c=s^{oX(2*~piHym#iPT$S8uG^2cuiKyY8oKtK9Pt ziC2TKWGeSZ%8KN(s@lFrmz^UQ{hoi!)Q)U!EdV3AHs;3w?>^zk$T2GhsHkHECYmqN#PBIO$t}bS+R}-6b)PQ!=K>9q|%iV z8`_gT)M;f)evn84lPk?uYu3_Lk0xx~?jtpubblXEQTH&WoY#2BmGi<-MAfWVOmN-& zDJEb}*e?e_&>3e1EB7LN1quwG<%+7%@DErD(8)rB?C6lv+{Lc_q6@I#Uwy6t(g3CE z3NVfngzuUu+1Q`1d1238wn#m)D=}&v&bO&^HuVs6#=NdMNiW{fM6p));>{ZY1!?a; zs{3sb`XQ7?la_Kk(d|mOQz}so3U&VAb!q15g&Y(xKzD9QXDnAS8Wq-QElzoI`&ed z0d}{Mr>hW<6%@#MNc{ymV;Z3c5xk!RZn$qdEatzq9bH?eVP;vw4(XF)*7oRstvA_r zzIpT#zA+s9T3mHlX;BXruuWX{2DaSOwP`Qk@u@8&y!^b99}vGKnoU?k9Br=#UaB9L zVHkqWNfDKNt4gFXXYQt!s=-zTJLHBCKWC5kT>=uDz($MzD5VPgD)xWAeq6TbVp9nL zyj?n9r)-zOm=1`d(&_3;ixg^DIEPBHKU^Z_3VyjY?PER1req$z$)HoJpU~4)c~#7u zw2MQoMe7-x^`9gLfSCHh`Fv#8xT|Z7<0z6`?TQ`fMmXRwYg6Hy4-bC1*qWq~;f_Tr4rOmL6R*)?f3a!V6-SNNLA(JQ{Yow-=5-gCn9i{Ni;o zz)_mUX-y|8fj@(wyArum1&e`@QgeZW$zYr@#D9^4P^8^%T+^>^xJW#a$Yj=N=F=BXO_C$6<5d%4kL`tw+^~UV z_|<3piXl6->`7!j1k$9&P3V zGdvhk1Nhdao72xKFK5Ig9qR`{W8v9I<_X9xxSsLShRq&Y4QFej^y&h>HcCTFytI4e zJ^t>?!2>;+Q*pc4@o4ZY_s3F4AN914Jx=*eY=!yGSXzv_^pftv->eo%Gzw_zsO|S* zco#fW@xJCxB{%*Ma;TBC*XQ@Z39NRR{~#w!{OA95)lVQcH#bFNw&^?sw++K#F&FJa zskww|RaZwA57D&C+M1?cXgd;M#@$+54rB3vFUf$ndz{YqqL$zz$Sy#W@IUA$7|>Z7 zovx-k*3Z#YI}3Z9prnHA!Q%g7G1eHly4=>)eJ(uinkA3N`L>U5&lbI2oV<>0`+!Cp zP8HdXuqCpCZ!GwGg_gXJm!EbZRNm9* zH&p;g&rLQ1u>gIc>%Ia1_RR!3^|2gy=V)){$ZECk$}7{2D50R7EP z+!9k+_xo{Et};XGlx{0<#sS(p9ya9FdmV1H=`m7DV1)vItc?HF`%6BJGEPG^?~$YB z)Bc%-uja%5y%qlVsaCTuC_ik>z+!x5isLZbcxaY0M>%<|N6+7F&M_{xA5js%qQe#x za1#eOhNoxPaYd`0eK{TVnz>+)zf>pU(gBeX-qtivFvB!8xxQlL5B@wh7AWM~vu+Rn E3yPVxfdBvi literal 0 HcmV?d00001 diff --git a/bsp/phytium/libraries/standalone/doc/fig/usb_insert.png b/bsp/phytium/libraries/standalone/doc/fig/usb_insert.png new file mode 100644 index 0000000000000000000000000000000000000000..a0e70a9050429343ecb79cd6fede60e157814257 GIT binary patch literal 562047 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

YFdb- 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∋yPT_dup3XD;$W+0hKkuhi;s(t`*LtXBIJb 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

IjDczas{&pJyoOKKCd?%3(H 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 Vf0PO+8ONv~Q`4x%whc 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
BC3k2%6e@zTo6^K$@zIUlpEw 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

*JT=R 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⪙#+dy7| z3s|O8b5@EYnC5^iZ-O|&+$h7zqn%3}&#J~a!o7X_Dt^mPUr=$bt`{FtXqnV)7x@DZ zIe057#y7lQ`SNW#CM9Ku;hM4O%GV;eo4Se;G7qh6UkzKk@V1Stayw*oxHwxMu1_|G z!&gY<4EduIeroRO(hm(-8nmt)q~Im|^?+3{RyRDwShL9&$t6^Ht5v-1Rq_zpsO!2b zE9+ZwpuVG=O_!#|kCTV_b;>?FoeYGbPntP2iVhDCLra>w-uhs$%iRa$l?57j`Gz_2 z@rC{F>>8=R~Z;x_1CT<%ZV)7)pvOsj0> z_NpBoY$}43~%1N&LYD1Hk+<4Nh^IEvX|=pIBwKS zzRO6xL`D=gub1gvPV-o07QSu@UFYuu-bc%L`TIWLV`(V?Ti1oOW24YA5?V&xrY*;5 zyiR=)OxIZTl~wBPy?gGeGH{^RPTGzG$*(C!pL6_Ek2MN5HtOz$?Yhn)*}D<$h&d)n z4~vTVioAIb5C(F%Ujhf?d_fW27^4~-<);&W!*?-Og_gk-j8gp7%+(Ik*HE7^W*(o9 zUu(-pUO*Zj7QMJ;jIlQ$`*kfjvO1T~s4G$n-EY!E+st}RgeN_wpnzokP9O-a8BR*}T zBOjx4=_bW)tZoe}o9NZ{)^MNk@CQHsVdnkagMB$4UcGufZ0+n08;rxJ=RQ=m9Xr7{ zi)b6{5dVM$)4%?Ue?6QZ9U-T+;bA_^a60U6@8sO-+tVY8^|PyI%xmYv$_4sK*_jU+ zb2K*72K-|55uR<-SXNS7fH;mPwnsh?L4B>uien5FRqutyvF()8wBIhSl_CG35qkK7 zX@;ly4BHR&8yesCk&xG&x1D{AS-y5v$?r24>C?N0Sc0T40|Ii=B&~Vq zL2}BgzI^nxVR73x-h8^{d^&Lyp6P-{fkuGk=)22mgU^_#nx;^%E~)Zv0oTiMbuEvU z8!}IdH^qByZxYrdhOP!eN4#t&TgxiVvA{1c6O2%rzZc_ld5y?-t^=f`B8uI^rzQdPeI;`PU%ELr%(OHndY6kscwnW^o(yX zE^gAc9T#1|8IF-M(yBJBvBdWzZ!%FiDf$xiOC}Nfj55x#rV+n*3W-4Tpx%j}@&Mxv zi$8^F+%&E88FyE{kAe5)H@;>3+roFEWgX!w3!X85^Eqw%Zj(;aufA3B;)>3Ylz!(Y zE!An!?F-Vr#t`!%MHd||P<*q8P30#lMXW`&+JfGy9F9TmvSH=8>*L_E;yAK;#RM8A zLbrLMGNdtKkNu-{tn^Iu##?~-KlT`aAgyIr3*xbCY9Q_0RbjsH?ot+~{PK=XbyJ`E z-(aAneCD#)xEl9V&;^}8|D@kwxOG|A?Q~lf9}4nNZJ4PI{+(9{g_jtcbGejm8cs1d z508(A{oVcC5lj7{b9#C*oS&W}XTOknkx!(a9v?>+&W}%Wd;k2Lg)Bv!9Gzrb_VeOr z=a=YXZBpc0{;9iisM)J`n&n;oVl!FiuCp3U)>-t zcsY6dYB;7HTp*kw`?Y`T&;G$rWoTY#7ceQb)4i6s0|K%w+;K9qU|-PgHhsc$p2}Jc zVVo5*GRiqRnIE&?0(YX)kaaodCuFs<7({O#bl7ONDOtNIa+;ax2e%qlM- zVvMg^S{-U)D<=kxD0;^0!MoY?y*8&tstCr{98QE|B@LU0Eb(_(*l#iC9k6)c+O6GE zKOpkx(ZhTi)d$r4oT*=w^7VH&i~-U*@tggO{W<2vB3C0;xqG|%{KW7155qZl@7}!4 z-Ly+Le;jkH96Z`4ircvn&CW4{?EcaYg1ncpsw8g1EuADdze=EFW_t>atKV@Ab*;Sh zi?^w3nC82cHv0aL{*2+^jCo3rh(p%)G5NLcc^uA9q~|RP*=@!@JI*K7y-Rq3J2`%r zFM)X!;2QkA4Ioqj3v6bl;V44;shk5lJ~#?Gc(SSTnAZW^aKLo`k9qmEbgfU$Sq5tX zUc2GdAbkhBb{*FZFy*gd&M*El7}xP#Pkq5Wx-KV&_7PO*@pI)0H{jncZwgJjX$6p( zAqNv_5D{afI^=C0lg}R$@F$!jjQE{2V*m0=x2b#Xr2N~M@a_kuCWb$rdC0li`W!`-0S}wPoKNPJET*3H; z4lfVf%1$G{uUo!Cm($k`8tHWoR^w>Q*EB|)fHI^!jsEnfRHYUHuJZHRCGr?;+te4> zY>)94HTf$XjWII-KI~+%NZ6e~`Iko@E*Zr&!lFK12mP+AVEqNJEwk~wp6ff%`GoeT zG{x=fZv$~HtHXD>%u-{WEw5ddAx`r#7di@Rl<)4$y8x+MzHF5Rn!9p+``)%Q&TH#G zDR+cvnXNM&-(^qZ+MlNXHt;?g#($`szYRW?R`9JOd78JT(RDYh-21xmI$l`d`o@mB zOW+ZJ#TWox`Uy5j^%dGM=h?~baI4{I8#gWtl@Gq-dFg@U3O;4n!|KfH?e?{l|1ynL z$yc9~Zq*@ol^kL4EK6BeJz$kS;ag{B2tpRj;i60fJ-ul%_6aTLyI`93KAgKiURM2B zjq;IIW5)SIaa28|Cr3p$vczW;!lyo5M2|=a3G?X@C$86qohd_s$mp24O+$|yCs)=y zmc^JyQEtraAKc3wFXuvK=hOT?J8QFwjJssYeCVsDj*oH+-s41G zUxVk%{QaD&WwK(5vFi?R&bMB4eqWGYAOd{=5uSkFK4Z;QJ2j z!{M9-!0E|Rc2Uof-9^r*lAxJYU{!L9##8$snaj{}!Nh@mk4a%&n0-Y6h(iid?0mIuU+7o^|$1j8!k zECyODhqU20w}C|p>KvwcLh7dP^+-3$LrX;D7Hp}{Xk{}@iaq$i*Fjkf^l zm2oPxjIDD!<64f&Q0LKymW!Qeb89noe*5+{hPvlP&eQ42Fmj@XI6b7QRCP@|%OBUN zpVbQQ@C2UchP0OQCIrg7)(ADPtZtkQYZ$Am+gHN|2J6ZugTlr+2|ge&1Ah}mU1Q~i zu3tJBVNjfp6Bu;!lqrL6WbdFxc@|fUF5tGTMzEQ(Dq5tq+`27=s^jhWPU|*qn5Tg! zt}gN8U{yv?<&n=RzEB2H(?mcB35@I(SwANw`Bqmn&f$Rk(lMPMX~w26lJNC~V>|Vr zbiQ7LWB(|;obR<8`N*9>=xDP0+;il2? z-vy?0r(k@``?rOUr4@X5non@Vb$#`{_1@?F!5;O&oF&Kk*hJVo?xbp@>KwlWWox>N z|2n5BB@7b!Ox`;zUHXG<E~J<*B~(GuM)~w^(w3e z)Pu&m4VLwN?yN?p=>jF2l&gIB`HH_)&udal&UIQ}#|k$oGF}vqZWN5QfmX>w*Zk{G zbyhH4xT}r}_<9|~m&X7SuC}W3EL*?Y+-v(_!u<1X)`=|{B-!_*(bv(Mw550)Dz*%&oW~m9UdL!6Q&oWd;8zB&yf?q znGb57)NbI4_5ow|#mVV#hP${tjbV0idNy3oF1(32Y{(GCxl>J4jB8~eqfraEbXOH` z4&r^QvC6MEXB^9az)z}o`Z)Cqi7U=m4NaX zLtaHtXIE7gnW#?bPo=X&apXO_ec(o5QFI3{S5XL)nHV8_7$DBN<|(3FItbW^?gCKHXm97UY_&;R{E3G%>;r3&85k#}I9z+2c-USpejRxdt-l}2)28^N`{gZ%+3%Y%dcS`k8jb9*B%D1P2v zYqdbQW)Rs}!Z%{8f zzQJ(x!?q5s%9D<6Sa|@(ZL+{g8#sB&JI?gdg_5gIoDFb2$ zugHxX)6!qNui&ykz^^4;9s97%o}hdP%)YKpbUmz-zH$0GaT})Bcclv**YVx2x(uDr z{uGSM1B@e{)pJm`QR73ibA?_zwQXd>E|k1t@)ur`E>`7Fy1Gc;4kojSpX%J*^K7y2 z*Y%i$M^8q5bjQ{F@Ky%B1F<|o%lZ*cef%5w3?IRC5m53}z72gHUU18DT)zG$Sf)J% zJ=%-GEyM8hLfO)%(X&Ivx7T6kD#wjn2NzY{m51sX$st+DM z$@`D9u(K^RKJCYlwmn!@OC=3sp0yS7dk2N`Y&*-g<2Zgg)71IMkzao{EwEPiWl6IU zlM*}#MvvqPu8j$R5*pTF>N0M}DC2Sotmj?OGWrx;si}4XJ0dQg%+TMv_{2S}#vjysxn>6mC zzGR*glA~GYTw{D;glV*D zoO;}gi(wPpQ@FC{J4VwcI#_Yu6#QS3CoVBu%RBz$5sZ0S2O7V2Qo zs===-d9%EgOKBolu8T_X<5>}hrOwkGMu@R2o)=@9I2sFHTb7NRM$46Zeyps`XPi#F z_D7h@P~}Y4DznQKI^4PHs+3_qQ3t1#Fzqpq1JI7OVKZ%J-1^2=-c_b7e1(>a3e$X` zW*Z|k(vnr;oP-tklZOYxlSiKnzx?GFSsCu{?b35+UV2o)_1b;sK@r&K9!;-8ltP07^U#8v9&iF_U|)z+=HimR#F@9 zaP?}ZHDqkNpPw)p9q$h(&o_qiL+ba2!RLbd!T*h`Sn#e_wo1|A*K$7$YB6J5wM_MG zf8+EUT5r@f{m$3@LdZLV!RuVj1+n=WN6zymws4e_y3zO+XFJ<2(Vwxr(ls$`XT72< zUUo-`7e~_72GS)yXk1Ho%+t{I)FAjeG;VXY&}U&P7oq7)(b;guq~uYK%S+#s;b85cY=5JD$)nJ1U5m93XS@p!Bkd(Ht>v=}#<#vrua{-r za2Jh+yYL0`ypPuV^1QFzmO&cL(>#wfCw!WoG~(SA)!?#zZiK`_ahZi8?68P?@bJ;_ z_|em0XS*JJxuETG_E3Y%w&l;G8z(HX)0XxD#)SGJP`$y#jgQ{Ry}HDp@QGx`FL%yd zsI1{6m9yN8yUuTUWm1s`&|BJFmSbdLgm@ma7Ju+M^GzkG*qBFs78Fg{Inw5MtggdXy*WgjYMYE5`K$hCJ(P1TtVtN_lXsqm zW%S!PFKDaGS)(!I{~C&_kF2gS7kO#6LI}h-HVh92O{)b4k=6qln0)OxXSt;+lnIXQ zILcLgb->&FC2M7lE*W;5RhIHWoMGELEVwbieC|V2b;QT^FPgJ!U(8RQT$et{VBV%M z@~@u_qv(V??($~s;c1;YSKZohQ%_rlcx5!^yTr4Vie3@a(|FXM-FObx_!>tXV>+BW zbjcw{{Koe2v*jcwHfiJ4^aX36-_{TZg?|4r9s30_3rCowO`F>osj3h z`)~bO&a67=RbA|upyOmFf(Nnv+EIX}$UqsBg&$6fmq025J!PZPf|SbnS|U4_*EDlw zG5c6f0Ogm-RANpO9v~y6;#MTR&H9ozMSvs1m`R$7Fr9A%`D!qK_#dxRXRqK-64fA; zTJ)$jFmis`}$#{U=9VJ)bC#-~glJ?=l`@@%Ce#P}EdE6bYj;m5<6$N`~ zCqQ1MpK$&I#HoIw)PSlP%LNmVq8u=MGx@U0zs87lS5;#;=T%qg$;$P$?cwHfYnYv_ zVK75~MmXs#J90#GWTD3eb4V{` zaHVdGu)e`^aBE}O+1-hsqY~)bVw{xb=u0ExhTN#<(pJw$K1R0;?~9w)d4vw%h2QYL zG~@4bmhnEg3twnmx+`7RI6Bol7+Xr zSa%*uCs*9q=xr!m<^?H?Rja;N<<@vS*1>ja8K=LLewfdzejS~vU_UiBdW%sLxsk2k zB#@dVPFH1g-KKS2cJuO=!1$E)EzoobMP@Y?!Y3|sqG9N0P^pIzDtM_6ygCD`%i%v2 z!b{k^od+-pT2;oP&t$X8K(aU{J8qkbjK{pWmM>7NzKIUhI3p%=zEPZ(!RMI>Nq zvVt5VwbSG(DDqPE&Dc2BU!K*g=nZkz#wDM+cK7ch^lfvUyMp=5HinivmKs^v{iEv6 zi!sR5KXgrc*@dR8)ZaSEBP_(1XY?fe0!nYOr2^03M}vsSa(ld9$Jk4&K*P6RIL4&j z@+^LMU)UVN%)4$RhOfjxlYk>$3N(?lIR282e~QaArIjEYn5UvCLuBWB;**`<3Ucx} zj2mRD91`TT{-+%{O-By|Ixq*O>F3 z`IV2{&(>JAqV1yC<6txuLZ`LgLeg(&8XY#>#*0*}=!mPQg5)538aJ9c2lLu+eM`c8 z3r8i%({3KmuMR1LUzy@e6Q+E1Sm+LIoyC=B3D_)+H?OyyftAZu4!|tZ8~S?cx0_x^ zp(pXeyzEK1>*rwNB-!av6qO$#)h*n5<(B8}G*YK8c)xe=UJjD`8BuS6*vZ88)kQv} za5+2AuIMF7wZBK)gZ<&{n^)Ok@V$f{1Nil?e?{{_J2IlpFd}UrWu99QR6{Ax>x7%1 zE3)G%PutrCi0wv?cQC2dv$9S91l<4jEdYk=W}dsZu1c@2H-?LI-_8K}YwF=@%|~1@ zdLfApmEk^>XRRknxbt@Y4x2W09p814$LY1uI6CvRtfw-c%CcQ(@W++^ z0*x8V=^1)qhLRJBii5%@NJXm5vwp2why#d-Nc zjV0v3#Q?B8@#rg=;7OnIF&1-+MnlKRkKt*)sr;u-xGVmfoNyOCVL7gy`0q;>nw~I? z6Z*Qr>%!+k8G)7^F2>pYy`ACFu;Fv6d*S{f_m-7Z!2sqq2^Mx3fs)l>WmH=g|0wR}Lsyzr9S-I6hqxybhE zep};#)wJv?*SLo8M@Hv9%MmxmCC<&0di#g2p39hd?8l7WdPZ+FUh_SE(lx?7K2r4) zsoKmuMzk@k4%QezS?ZoT<^{OwXwMZTc*4xVl9TH!5NIpk&D*a;ELo0uM(8@4rjwUu zETtvNFuW+u6i~8A*gPX&#h>gV!^i~|h|9P|9?SA>MUFz{+65bF8m!37U2u1D?VL9; zKDqYHsXl#YRU;Za?_wBddKQDq6h7)}Yw2~AQ~m#D@HJr`*TKMbm;K-Ur~f!-R;{dl zDUtFkUr<1$XjEl%;&xp7Q<&mY&CnM`rRegI1s#S8li+pdNh8o;uAaj^&<&FcnRm%a zqm9+(MS8-VCJ@}wH{M$seJy^)lLzH7y=g@@V+Z!u0f_TFO@Hc7!E5oFcdzw3++et` z8;1~sgGJUuQ5u?SH;b>iY;W&p*VHt3Onq0J#;Q;C>(~1TA3*Cm2CDHhI+l139y}Zl z-@PUc`b@wN?>`(K+&>szzkM}4VsiNGvrmU#{_+>YU;gF49yT`Dhk6HPsvhu*K6bJw zuzZgRJ&2?ZgjGZj(p&#J|EuC6C#?YTdz8UWKJ$H|;Mr>SbHCu>57ixRE|D_^>*Xc+ z(C>^5_9zVfL8ot*Z z?(4>xrcL==zLpn3+|H}JP0KQG=P%l+(Hyt*t)R=8rcHgF&^!tYy0>}IweG8@(StEv znBsN0G&ut({ERqV?s8a|=XbD}#808~OkLs`7#$*WWn9X%oxwpD3r!8Qt~bNx7JYDY zXV^d3rN6N#T$krMTdA(!Fu~bhrBg-&^+f-j;GHDo(uu+JGLmppJsF+xkpp13+jkkP zSHp6i4{@zO%OG9L6dG6B#&;Qafp|ja@9VBp$9r9LG!EUBxyp{JUvs;Ee{cBw^UsFQ zKl^NW{K)Z)@y^@$(&8^i1hU`4CGC_mtBwKL;e;l5F-FvF%e}lB)@U~;;oJgEKFXJz zd7%|4VwKLUAMGiwb3>eOAX(cWt#*X?qYfL<3UAHE7;$oiNNpgL+=Q<4`()N~oyw=< zbsq=jkr(SVru1?}+dW`yM_PtrD2;tdJFk7II#rHGWV=Y-`G zeJ4%BxQ-W$1`P3aKDKZ)qtIgK>ZyPG-{=ng#%7nwu4$83S=(%RarXw zOqZ)KWH(j$R1>5w)~lKV99)vD>pbk($B!ZtmTe%OIK(O4=(r1$v@dcAU3XS5Dd&puCwEpcGTm+UE~>u9J$?*+^E+`5D%lqDQxRXWyK%kh0YH~`D46b+SGO26!Mym zX;jKvM98Pt&GVFw*B$0x8Pbu*Vt_WyWCu6@*MLXdD7Sh3(Vx0+iktdfXMLRpsjDjo z@-|ktm@Id8{Q{8&Y3-`+Z0`=+yF0_y_GVrJ?>FgN!9ABHdBfuB44c>UG`{Ohh;>=VGOeJY@0YxQREz2md)ETn0{A0 z3GwbqQ*UhtX-=I5TWfVt$i$kC9tq4D6SsB0^F~gS>yDeIb>0pOoo4*>x^ddi02?mK z)$W3M7Wm6<%7;!^_JwI!SiTmlZ_{g<`a=85;J{1CvRK#eX{)9u#JdAW_~y2*_STTG z-E=vpH4i(PusV_%#w&O6*O|!Y$7@mt>03W=%q!ioyn6Vw`eG(7Q3&Up_gMCaLh>!S zmVxelFvb56HBu+2g{?*MlG zV1&rxh47URTiOm@N<-PBFPQ^Jx*1Opv=SyVV~lC(m;9yNjN`Ty|LqSp4C4vf3JR(4 zZkqEeQ>jfH8pF!w;KR+{A+m>$+(BccGlA#a% zHwD1QDh8sv!yY5!D*Bxr=NgQYR|CPjcbVJx^_ZozZx9#>7vzdK@p27L>rmC*aP^Dw z&7-VK20@WO7?V~Oc9v~IcqnjQ@H(YPo4(}+$OdzYbJY5}I#VBIY2UdF zyrzBBowT5f6LH`XmxYau>YqGNUg~K5fv%qrA6nV8@o&VPr~90XbwkH&731B^C>-iN z;&G93W5`d-9OWuRUh*){GU|N#1k{^nTcjcH!3`Vw9XshwaUce#c%{0N<=Rsa^f5SDU}OergZ8RO@)Ohka@ zC@NovX;}gA?Tph5&BN61attRP*X4G7rs=wl6YM~ZU*zjG_-!N#%e1C$ zIbG;**UxmnSG=*wKBXZ%S67=SUlr=;rqb>Mk+WyF>6Ovj#Am$tWRr-myV5r zy1BJY+sr~+#W>hI7<}3M5yt7>?sjhfA0HoLteyxGJM7W9zEoX@sI>?&kxl~&Dh1<@$7@s!bvT~FYGJuL}Se*D$p-x>-BGdz&GB++^ z{0=YjR+}%orlae+Ow)CD;Rqey{xq(`-vrC_`g%Ej8K&u7me8_jFijqsreJuUH@^e| zQ#}24eH~hi0b{POLDRhjpu#QrE3L*p>5XlTLe->+qivngGw9|lwHO-V>-hrNE`7%L zHELkhWMdnfkDT(S-up9bSq{Fqye?^sx7@B*jlnWeaot|a^)Rg=c*!@?us)Trh+A?+ zPONqfcjNPSN1U$9t#qLlq_!z>>bq1UOZbdFcw}j3xOe|xc=Gh=@bt-J{Kr`YSl@LF zMi0)*Qn%>B^t!Hsv~*+X7C`(HX(acjJAab=~X{ukj2v`$f6 zgqpz?^eAJ~B`II;aJoYarVsl2R5^JRQPrzbBo2_-CVYpYIz-s<=E zqhD{imrrFHkM=X*Y;t`teER7Rz^A#9h4_kWb7PA^_GWne_(@*Jb9Q=02i}Te^`QU& z|MW>jK~%yxMNu$Rj}8xWE<_{NcdPoYRatoV?#=N0`San`%QucEtg0}Kk%>>=hx@8x zc%*iOsuL)L3|=}r2Ju$YYbOx@x1Fst%ytCP<#gn78m-)IS|=!w02~sfaF}mL4Amk0dKMZ0rJ+s zr!n&)fy#wOjC5Z)mW_KA2+e=w!R_>DXL2F0%C3ed1Vt2zxu!4XN!dzg547JIF5K zCX2>(U%RGm_`X((^eBy!O!bX2a->~@xpI*=d91p0SOCl5tj3=0J z`7gy8xDHC8BMCq`wu3S>i*CE(q44ylY2_e^Zm#%|_FRi^@2E+MnEdPm4#@Tw`-QLc z*`of42^nn;4-U462lsY{Pdtgin5V`e9|Vr!YbvZD8u5FK^LGG{}Rs*E*B02gt{Ihz>BsOpUjaCxRx4O=iqxQ8X67rJ|HWpyJ^+z0xfWDa_OZEJ?Uxmab0s&665E=Hp0GcOBK!>7hNCgL_z9~X;Lt~7f#ZX zhGRm`Zkryugd!QB6bxEAB>AKDt@(nt- zFPBUC;M954IyPZFYtA)|u;mkrYAG5S0JoC6d2Ef?4a&tjjP+Uh-~X@wQ+O}&^#obh z<+l(UjH|||JSxD{h4AQ?b4BAhk(!8>ow(A{?@1&UJ+;a11+LS(%m(v!o^VX-DHw6( z(RA~4Swff7@dV~{+b?{4q$w{dN(75fER%q1fbqJ>76U22^A~T^@|Iy*=dS^ZKyo^0 z89JLWQvFos!GSNu_RAX>o@b}on%6+x-QOFYJ$stL&DWGD13UD~moLJXFVc3`_05~t z!}USrDX!y})0@X>x;%9JT`=Ww znO?)RUV`-cS{WHOuR1nO>-g#QRL7@%K|HS;Utd@BoUj(WO=&iWH>Ic1piX@gm`9#l zXFX5n?W|?mLdA_^88}xf=nGLd*B+yRH{w0FO#oeDC1u}m(uMcD-U^-d3phtd$1I~} zISY5iqR_s1j`LlP>UGsyaI71Il!`Q)y3@3vdiSGq-8n9GyD%ZoBtg|YZRZa0Pp=K=%j8h$1tXrS^glzn@`#-?M? z#<0f%*nYRZ=~(8155s1YiH^RxwXs8Xc!vMTx9jR2i{vMe`2^#}v+H7ILZ+Wy5)cR2(s+O|d;8+~TsruP|rQ?(Khz#rtejN#;fN<+<=}G0i3rw>SkoWD@qzC1RnHzWK2rXf$G@o2)e1(4R1i2^Bi|bH!yEOyVVFhZ zVzi~+6y$ED=Mja)hc-&?(HH%+gXxp@P{!l2{?3yvBYpYyZi$rgTt(=+5n*f6=FaD%JQsRG3JN~&VJZu0b;};fU`%WL zYrD+fJ#SgIt30bPYW0qpuE=Ac{jAoN3{J3gz!oIBQK)WdHY~wj^iKorX8sJ z`W0K+(7d4 z=ow?wIdx=&$nFjxqYIS;g5A8zC!D1Xyu$xK{BQo}F;-j2BdiF<2DOapEKMK+8(qig zi!;URaK*c-sX@Kt^mS7@f@$#`VBUi>4Y%T1q18)qs~*jx(B)0(bbT{mj5OwP;Fp?= z<&b7J$*G(gtID-hX90~bt>tpw2aUH3PKNSkS8|u4&g0Y>IUktvlc>8p2kC%0FM?v* z86G}*VD7|gmuu5HEae85*$-#OT>Zq*K_yB_XzNXz{QMhGS^sBWPz zo9Dx@&1!9%iD28#KTfiCa(7AO{fxo<3>lpx-wOtZ7_080+U^VjPH0YCbn2~*T{`bo zCQD`DgJw^jJjqdq)6*ji_r<4Wm79JKlC4MGPOVddZ7WXePp5UBy4Edptm$;PuZ3w? zkap{Cr!C_&G)|{mwt1Jq_$jTaeipwAXgs0Q^p(#tbp0Bp*IkC!J?T#A3C1-(p|oRj z_P#QkPSYrEx z#xX*nhJLSI_Md53951*g(&!-|aI%%oL!@_O>kk=4KsX!l3X? z3fbW$YwbGK7Q#aWw=ZC&rZv79XiS3s^t8 za>+QOv8C})?~N>6cW^B;V{CY;a-(~r9DD#IG7L^l$kw$U4%M#IzyL4rWW{Yb22(fU zx2(7IlbSM)p|a?E4Q&7jF?`H}er6GrF>_2Dq1sAbi^nOHepLE0ESKBh^8guFk%b!p z@}u0~csNIA)jc0Nb78Ms9k(@kEkl{sv51nf3nzE1ox5|UnBRqM2yWg%P5#JOR;;RY zq-NTZ6S9MkOx#^tL!P#qb5n#K9&8Wvhd|D*5^H;wo-<#`bHebAzI0ffl5ell$F0~1 z&JP)*`1wp0!%(ihGZ&z4*BVjek&c`?9K^un+C@s}cO{ih*9R|BP~T0JIBDs^V+b+zRr?bI;UsWwkg`Lig_YqrKpiBo;1`7v&+u=I%bl~FP9Wd~dhUE4i| zdI-xqiH5~@`<&|b=c&W5_5t$FSE|UXTyxhbd8x}>9s*&5iIT1^2|($da$0fagKur3 z*Z;@=?f>E?jl+e7>NJjOKrWandgBQSAw(#!2UKA?xMmPxQ0_^g@jI>Y8j{Yhy2jWL zqibko7Uqhr@2Pil6YhBZF1KNxhO@&>ai?GoJ4(XAQ$FNb*^B_iPGyxyd^N*#S&*RyBOVz9d#=C1P5(NPRnua#Zvc&TP2+?q?S{r{=)Nq7KZWJI4b%Kn9t_`= z$27;7X_|4Zi^exi{f_gUdj!6g*7+KmE?S55@8-E-IbRLj%Cq8bgOi5Fp>0tEdIp8D zh$$`OebU&cqS0C+I$z;sXWyA2cwSc@)wXqFx377vA#{FukzEoCavaFf83^f|0PH)` z$pmwo1zhP(&QV%c`lIK<>OnBatD0oSNq*eK$ponLHiG_U(b4wQ?4gu7YE<6Nv=?X$|EI)WXS8UgF3RB0eab z`J23}8mqypye*^5pM)(pj%&-zcqJ)*zI`IMw8?6Ija5@*R64Tb?xNTJEXQJ;3)@h2 zQJBb#DFkC*=`4YElQ;=g|H{+5y@{v%+LDGX$!CLusjcd4l=_DOa=|6;TKa0GLc_AfF<)(2S3MQ55(^*l zXP%KK!=)VLU$3){rd7tm_l#RBM$`PR5MvdMQ%T`I9an=#p7k~Qd@F!YKWc1xdu457 zHAbw1r#pqh-rintX%%Q-%rZ{(<1`X{POv)hr`2H`Er#X2zdAQ zD7Oaug4M;%DVkAjE>s)WMCv4&>!eTx+Y+JKE(nVJb%f#qrB?lO8^>W8<1>1rajifJ-%`*9kZV%uf@yv2;CGUWjyiiB-tr-F-m-l1w!=B$iXyk1?QLonetFc zSf)HDUTAB`URj1SYi29Q*AWj-ex^JWAVZ9$k_lI416grga&hTxP~vB{i@U2H1t5>p zekNgl8dyGTENzQ|!_e!p0AxU$zm#8$Y$tL48}DNu?m&8^KpIFZ$BtGq9-*s_UC6?> zJ(+ihMfNqT@-3`bKcCEB=(OGmF^c#pAM;xmtQyEz4)q%6GV}G=B*@=X@1`K`U2zQ&9fqC5-J-e7;{GZ2&_1vyPkAzw`lne6Cc&`pYNLib| zZ^@^=>b&iEtqwK+MWkd@*Um$!2Pm=ajJ4R{F2<0C?B-E-DTa3pR6)ER^K@=_{Qt=N zmtM=ZZO;#y>lqRIoRhxXi*50BD1ZZU?Hf42I)i%A%!3chH9VR;+}Y!ztR4!)rk9O>In!TbhLumnJL4(Vy+M)xgqLRRjXSapm9tMcGa zcOB5c=9SUb35Inz%dg*uj-b2+t{!6GHMluwkUUjK%9AMSS3zgUyYZl*9B{8asWV_B zNgv(jMgH!fO8607-oNi|s`46ydK>P$5AV^__Y_uEgEeV=|NRfx$OZB#Z9FXZmty|t z*ME5UoBxmhE5Y9nw7bY#0q#FNLX-ZzypOr)H!bmEd6$W9v8R)=k`8VZrORkkzX&oF1tTm-f}hP1FS3@-g5Ic;{_Am>w`YU z-s1hEKl;PyryZt0>&Nw{ zfxS-)a~4`>+hf@t#!aLhoPx&@sJfTX=kw4*QrOS&puM%f;Ark06e{97$RUy?kxM@EbiA~m^hp=-`hfBm zU&u_g@Kc9?q+rcL3%=vYi{1jVs^f(Vy877;n#y9LjbWM~WQ0;_!C1pS3qN+Wi0vr208K?tY-Y7*Od`hs6oS3G7M<2sjQqxhfW>WN3cxZt}k#-S<*Cj#!=^M z=BFD1RYPUX_zNz|4T$U)*H$-ELR%dujGg4GYRGIb=tYuXxwy0D1TW_%<}8e_q(2r| zCQt3J-Nl~TO9J`?;mYCeb83sx$15lyvVY>jEjxu&-Gl%1U{DGl^3KlrAfLAKOtY+= zuH)&OTztVb7kuJW65mm*Fvqb@T0Cra{fw^?^hX@)f+8mq#jjno;UZ7k$4)HwPT2&1 znZK}s<*tKBwE`{I*zWGm8!MDQcOOEuz7;<59nYLM0+VvXB4C7CB=hD*01p$BSe3>8fL2A9C*LysRxj&4psil)H8G5tYiE z*HStct-QZNb-_hdL~(r3Mgd|WE@Uir=QQz8xTAv?@9@)pw;Vo#;adLWbHT)UZW8Hl zPivkFMCrvdc4#l!&yR@%=m+dRcOdQM*Ti!+MQ@I)|I~ltKfb+ZwYzsJ>Lfu&Mzr-m z+IZ+ZFp9&?AO)X~4lu+|p^ApWs++WfBy$DCGN8;;7hx$=o>6dMI$-LA>33y_gEIIN z@#}ydda^Xc^8}7Govc(T^d-9v(NHl?;yHY52VNeM4&PuQKWS7C4bs(ByB$d?U?pKX=i&8**|QTmkMkUhNk>?zjJcFf{_ z;l$ThdCTR7K;3WUtD`ddEbZ_9x!*hd$Ns5*nn3iIhu{0X-^;sW?Z3x|{>HSEm$&={ z^=w~ua<@*Lsha_pvA|JW&hdHWx6D4`lO7CSj{%btRP5{a{wwU;S~urOE02fi zS?td1P0v}_*MF^S=zi-lH1=s}37+@Ifa$?IuM_rp@hH(9Hv6=!c++=#+YO|R=g|9+ z1EfJIr!NnOTJf6qNy~ck7OivY zIcT4hGAWxulQKA#sci>-+#mcdJrJ zS}~|=zGv+{^N{tKr=%AEV@m_J-+_-aKt6T~$=GZiA;w8r@TK~ozN3z5O&(u_pO!K2 zhu(;;4jT?WH#Hu%)amP76 zq0^_8{^}T(PkBYB99&!w1GLX;r;Gp2zxprdF@P{-&`Lo17hZ9-c|fA6gXru=+Qv?C z(pA}~*N1EoPhH#4S4QtXx4P)qM*Nw)<&s@i6me3wy}xAe6vxti3c-z>N4cI>^lqJc zxV3GY1gsoR9%Ab^xiw+nrco)?k=yYDl{q|;Z=L_+416rVe!1%615s(vs2#^ZjBC)q z0RbVLADXCuRB11rE;i*LjqEUZ-s$Dli>+F8EEg_b-=&RGr;GhDQl4?O|3=4E=3@-n>RG$!tXJ6D4|bH^ z&AZpbhws$E#a!RR51ua$|J0xRrw{++f8?J;w#&mW-+egz&hP$54}bU%{_ya3|IXim z+9iSN_lNJl{~nsJE7;SwywZd={wG-1w7kndeS~jm!^C;G(roDlyoxom$5`g!e@ z9PLbd_86G@fj$1TnRZh?a%Ym;)d|y1$e1H7&a@HsJcOZfUVh$o%FXX_#~$bS6W9ua zFASZ1nP8u~a0%)r-Qi{ayq#r2^X<2OR z0*(*c*r&q;1iy&m*}z#FEM}BQ{RqmY%+kGL{L6PwKCsa(l!9gOQ65ud>sOVz`b}Lj zoL%TI4)^)?`YY$!-l^uvh{lDFvtzl>xjGlQ^pg%X_|YP-=E=MuU1~UG%b2&Av zObND}r|g3SJ=T%-Lb{8u^)`0CXB~QA4(6i4aiGoA$HU#%YaLxew$fgvVeD>ryh)}% z1>j^ISy@QMX9f&Nd3X^=(HFNj%IF9XQb zR{9u+0#ao^=oj^awyy=v_b6}{cWl7f8aIJZ6!QArb=GP1)fNWCuCEo%e#g6>SkJS8 zWto)Z*?!B69e%Z=4Pz>KEjdPB=U@G;{n|Qx-7=5LS&)BpG0hlJ)@Ydu`p~(Y`n-{V zLgzFifUEz^fBHX}pIdDJ)gVgd4n#lg*qADfVpNoI09q#`Afzrk2`b}y6f9fTjSP2+|zICYMDUN)WU8a-l zRZg)%%Fs*Qb*{{Ab{ZWZDJL#)yrPx{x!_2@&uNMzAH`F^9)4T^GmyjpA@qW)8`;31 z%P%slI{wY1GRN3Sh;uqP!1LL-I#PoiUxlU22AJk;;sV>lvY5SN6UfLlG9c8&KbLkhQSRj~5Zoz+l`ypTIxVd`I zm8wp@Ycp+t8D9;YEv3uc&PX*np?IR{Y zg7)@o<}<6zFIqxxeU^tXvXf3d)U_V$asDX-ucn_X&w5k_E^4qe%7X?S3H<@ zEYhF7TcmA8TGUl!M>E&UVGyj-}rmDde9d>u2S! z{ghFgOGSOhpT`bEHD7A6FI>1|SMrd`mt?r&y>Qotk2=Uxe0To(#VBo}?C_v3ZF`mR zOM7`mKHAxz#syxOhkoTqy=|Rmp_d)lus2<~h3Kj#&3*yusGRO(?d@}NRG6BGbo9|b z?U3kb6*^cR8x_CyDvhI`pC3yw9U}ca>x!&qR}?T9_eAE_S4xr4r@ZCepq)Ahxb~P1 zKU1!e`bzk7DmAi>7cU6P%k|2`wKZwyZwEX%L(`lS)JeG?=_{-Kr5-)(%jJU{QzySX zFCs72W7nvxQ$9vQaOa~Xejh?%ytwH>FvYr=_pC-(^PIVGJ$O+-`V#xQF_yj%Pie(V z%1b2eVqcLUhcqdR&TgK7Y5;FgtUR-BdGwWx;$tiFld~;KHBC~RyC}IXT}adR>SjUG z4J7+ZRRdBh*w3k7z94UHR~amC+GFa4@h@?NY3C90@lSvlJq_c8mcckSp3Ja!Z$0QEpJVzks zuAMlR&p3&X?n)4~(R@B@}!awVb@xpR_Nb%eJ# zlZ-sO07%c<|Gt0qyYD_6{{G+p2l=MF?Qd_d^DTMP(^uEGw}<;5euyoH z{_s;%Y0fQm(>@FO`N1I30P-nx@+A_~vAth{a7WgDmd5yiw#^XY&qb;>zUHjH&j){_ z-Q86u#v9+$h{N~{>#u(Kt6arCKfHkRK9j)T{@Z`+aR1mZl_{@~iy7q8W%4cJ6}Uk)_DwnVV}0mUQS_OFNkwqR&Y+MF1dg$OUm#cgw}7d0(t5CrBdrUH|^yb+EXT2 z_E!39VEy=W0Q9Z{QcdGmA;eiF&FP|A?u-Y6R5@axD zm7TNTT$4ANP-Y+kI%%t=sUOh>c`wCVy165I?N9&*&#~jPnW8>QpzmGalUG(5l!66C zf@5@XE_c52`AY)N^FGTDCak%k_VFy=3+D6cIra#EryK+4zU(?XHjVtN%9C6Zuq=G3 zXoDnn5Pp;0HIKQFX(hcOV%FPkq6>Xps-R&he6( zF-u!y&i7RuGq23|2BJ%c4QQWDC5~>MVOr98W|<>zr@&uk3~SH&P}f?^tdCDQPMv>)^Vbn5zi?c4&UF1zJjIa~*x7W`C*&K^;{$FgvG&qNOUc8&5XAMb zgql>Bc?_^e<+k!#I()*LyypR_dyy6mp!cE=K}$T%+F)PA+MI|wyYAk#+^=7b2Y(pA z3t4S9b~7!Q_n5k4A0B;WkDq6Q1#y}RXd$m@_k~*<%$_epLQhY*_}Bise{BV;8rKOy zEIQx73*?pMtRNbj*pz$odTF&0cRX+K$ z>p(XxueO)x8Wg6P`OftUu9MrP!K(ex+c2i3aZAwV^P>AUDPLvz_MWeYN?jK!%MDfy zR1F5_Tkr;OKF{M$t9WAvcR`=Q@tc3c$HRrsH$E5yO2ab0#N>|;{PyEVu2(v+^2{uD zn0Ztkx|nprlcxP+V2g!wh1p$Mn{{$Ah`ziwFlN9o7_Tl2Jl|uNo5L@E-)(1xBi2_jX&XAPO_3gHg)Qbu7j}sY{06#`9dJ8UB8)qv}JMn{OdWy|3MqvJ)jbN z>M(qTy{uC|uuq@Y315~$*C2pFQys0>HpLOO>`vQNciP&QTRHQC<8S3o zWI@;F@P`mhhBC)Bc4(G!F_VYIMtP^RboY5ddD52oDCDWGjP|W*v1-TQQkZ#!F?*l6 z!&}sMnB3P_*{nQzn5Gaq(&Cynfq?}qInaZy`Q;AXVO?ppq3+o^$Gb?%z*KOx=rT1^ zCM_@xd?_~m z2gR$P{G^*sw#uVeu27u7TQ&-)n1^852x*y{BtEw~ZRQv_HI< z-z7JQOppUz7y0oK?W$dDYuNpSri;oTs>!DUa!| z$+f3B_ybetd5R&aj7{Wco=w)$5V9D&owB+lS}jkkFEt9`8P z#hdgVhTfN;zFw>-oczqv4`J7_>f&a=>ctyK%w@=%w^JPDI*Ql1;#^)~&;PCZbCCNh zeDve$W@-ENZCxVm!Ru&;JL;gv;sd^`L2{%M$SxR4)=Br2_LqF{qQjG4&Llmuj6QG4 zHD!+T(mTrEX4UUlRvq2R^B0VqJF~+IE=AbGMjrYzxHeK>KE6Mco=&~GXO3RDxphpZ z$)?`Hc*RIB?xHdu=!4!4cMFIa6+ADzJD0gDxCJzT?{zgZGH+)E@l1YvFm)W(Wyc$F zI`<)?dKam9HAqhKzrvTt#`>YSwau~_zK;>oMi9f?^oKBMX_(&UZPBG){`eRlZ;cxo zm5}t>7p<3`uQj?nJg!Y1cR#ZZgVT*2dX#?1J&Ck|hU4_f8JN&AS&!~~X^o_TMNcN7FYIh4gBH@0%8+djwMLNKjdI9^OIDuJOp=lvnfdFngQ z9NXA$Q#SML)Op0mId8D)_ApuBhT$U*vP`i0H~vTez1MW4jOl?s4+&9kb;Y<9%ww2( zR)~{{pSI7J1R@NWIk;CY-? z5NCJ}P1{VJf!LnT;D|po(w5*VWzhC&T(DkVnG9*8-qS{fd?~dya#g#zBH&B0lj=hz zR0FBliuyeGFCA&5xE-dWO4FZdyHS5?eJ;k!`{>H5+JVcQ$4sL^pQ`q$6GBeDYVN$ap)> z$;ipO_O$=jBtjc)DNJ8Htzh+0e&RA{ZI=t4*oeS1Gs%4h`OCm{aPw*e}d5Gr+ZOknR-fN?CV*Al05R1&ty^IO{ktGz=!wq6Fih9ysUS; zwf&K_{I$Dd#egWy$sPHNf6bUpp?I4B@URVdSrj2Yb)Fc}q>lX@2j(&K;#=Z?e z%5V;O`*;=g(3(|D7kj>z2n3GG30ldkpxkaD!EE%ZrsY1bRaB12sF#NEzWtIWMNta&c*! zY2GxvW}M7f9iL)9*S;qup$+}0PrKt-c9M4Sp$fg3n?EyUVY-FdVfOn zkp&-1C<-|Id-xtA%Bd(l3$8<>m-=r(9P%YNBkduMGMldKg{ezBINosaAs>C&0AE_V zzK?ZeS8~~60PZP|?m)%>)%w1VDM>%&DiY9_y!2aOTX9r@c2ZvI%luUoEs}|Uf%0~euKn`MDJ~}Z4PgDvjjz8VSbBZzE4uIx-_a(oFm+dnyuovJ z-=KGVubl0B`&K^RefaM19l`4RYvi*}5XCm`@{0e+#G2m~hsXWBL3_)6JmS@7oaCpT z8T8fT6}!G78`7GK{Ue$s8F%J9b%5`EMv&%PW#{E%rvYuGeP)aZ;!j%8?$d7Xx96~L zv*)>|KWAwUzUO^f7#Tc^dk#}Sb@CXV*~xRlUHN_cDH~88+X~X_+a_wKk#Xt;@y}_z z1*3;BY1=i}tZWw3ll~)b`QoGalqDyx)Jem6CeDz%ogXE^zRt!%zx-2hw3YKK^ct+BR(X~>?g<&Mt?C7l+Vup3yQ^wwVKC}0>pj7$&l=}vbK&D#UDUwde0}gyjf0wvBvhI z7TvQWPt_VFfo`5jPuzlO`A@%3o%yl%jNSeGIUMDzk2dr*JeHXOkb&Sa` z#rBE}nD>yuBa^s4{WZd$8zp#efH))TIepV_8AICp@{wcOdfw=8&a0c$owRMgCQHF~ z$3=KAn=mw7j3(`QPt){1FOA8IKQyneeeTrVVV$!a_Irv+`X?VZbcr7r35Z?g;`*Log7`tw#&ernVY=C`9PJPHh{%%W#sn2a_*} zw5ILDV|Q>%gA2`DgK=NSQTz8xbB~GzzN~R}Cd8D{UVip#`_|oLd33P3v-lv@b5{CEC8N z^_gp?9j7gC5vbzl6Ege@s-9Mu1x48F^{wzVo9%TGj&+oCwbE(%yiM)avL*8Z%SuxJ zIr7{?aTZ_No=Q+z&vhJM5%%Tc?R7}Il?JgVI9xIQj;)F(SZ3IE3f3vZdHJ!OFuX?| ztFl;=?R<7@?_5)EM_rr?Z0fHFs0qqzt*fnTi;gvyIjeyYuC--}g}7J&!z-&(TcFc4^nU z`9hZdT7T*I9GdN?uFF%GM;B6C8Z*}C6;?v{{%`-Sf9usNkZ_HHy#h37&6fo*vQFWb zbMnqE%Dn~cbB#VUeL;Zgt!#JroWk-B!bA^{!*JckcA}o(wTA1LSC;T^fVVRGJI~S^ z2d+xT&OB{@9MCoLoTuI3PTsS$EZ2A*G0LL7$D6Y?FZX?Bb=s$VwGqru8=-P|%tTOG z2gG%US^m-;ncA+j=P+;m$SR%c<+tB|N!>O525jKY7L93BeL31SazgbSHYs^abmEzo9Lt+U!x8=y~Lnr5m|!^auN^e!D-$ zPJ;P!7#c@fN3cwppVp*)PHW$0`28H1_Iuhx!~7hAxN{7c9-MRD=B?ntakuoA6@`eq=BraU)kQlG#HV*KI*cs__HDS-fwTD~ z)X8~h$TQhM`P*+_(jGYCgXE6wo&Yem-?ukEzJA^Z=Q>aRh=V+9H&{4nOP$BSv>*PS z&-smwrhKb|?W=+0${fWKCo9e5($-tdbIX*T=0b;Y%#o7(Lk4Mr>)hfL>0BVLj}pnL zw}2g^Vk=u4J5@UG<>mDdF$i$6cm7Jyqugmh+6gFW$7a_fVKfnzQ~}=!eZGUOO)>|@ z&+9V{%9_quUC1?<=A)35*aL$9V^34kSaM7s6k4|re5aqR%R4xgg)({S_p&xv1*r|r z;H^@*T|P1oY_e!6`pk_5H@dLdgYg4$&5tG67yf|J5{19~3$Eg)AMtmG;%u@6NK~}7 zhQ==BHXYkvGaQ)y)0YM5NJy(;XK_~DU<9B!?CP^gC9mw}wP|TVNk3GM)hPBY`WIl` z^nt(P=mv~^eC#uMk72%q_$VO$#2B#^>(*(^0WNfF+r2Wpzexbjghudtt<{OQ!{o3cgQy1a^v zzU#Y4wJA7=<4$_!Xm=>mr=$Ck#z1TV+siBZ$K44COweiosr(Ka0}g}C`#ax8Fn;3X zg{=7D@#>JWCw6A5KU609dfbAR9oGE(YR7>AvOzHM zP1+bVKX8H4VAVr?d+{YWR!nK{`SL&*4#2}-6zT=b(YM4KIfZlE3Gx%iW7?gAbZk4c zr+@eOZ>2rbKW~8Tt>3pB7=E6upW{3~a9+0Odrtc#ZwCNl10ewk7hRIl>cQ|I)dr;U zupf)Qmw|fcB>dTDpzBK@1x4f|ZYY!OMM+^Vm-5KRGS5F|!-4ThtdQH3P=E`0cS07e zIo^V=@u=*|r@Vc1<{ZZEBhUEVzCVP~X<+huT&2DySRF3oCxW{9OLC@!JuSh!dW;-z z(VsT{e{sH`+%}opLsuJiJ{8Bq^(uWr-x_%2Vwy>ZQ>KK>9nRa}`i6k6MbPB}KD(5< z0}8o8(=RkJSK2U-OL3+=-!f2Ed`2FT6M{MS4-EWY{~QQT^X|sJ1+KKpIlD>1*rgX? z(nx9ON&h0ZdP~~5bHH|a&fAM3%5AFrwYPZAr6@~Md&XvA-nM&)&GF4V`zYTflQeuB z49daV17-`)bI3)2uVtVPvQRLAtdx6^;rA2d-p9_++j$a{hqbP_#*FR_;w!J~Qgm3N zTh?`=bI~R@`YV0VQeD~k7+qnf{XCP8-n;&>{lLuWq7v{T+X7Exp_-rLC^f=dzHC&*P)7YB~#$`8e?+QQBq#LGOy? zREQ5yR{ylHgTPze;jwi0$iiTo8wL`#bfMO!j%Rl>ea)1&_oZvl>8rAy;HAmr?X#&a zM%JsVgY})y;4V9S{&aV^e}2d>Q+@vY2v%)w+wdnnLFTdCwtYO}mPzTm4t z<>RxPUCmIgy_Lx;Cb3lnJ{GolOCKs z-E%y5$8rW|>O40fpq&$O{{qEbI2h1gcgTESf$8{dT9u2}on$YiVI` zxA0wh>~&5`F;~-FRs5%5n;p^))MM;nunL1#>|o@|A_kqkoO|2u(}MYtb>F9W`bwRF zGDglXVf<2Gr7F469)fcf@QWfWI?P0sld$8s6dTW4lRJ2?D zJU00PM9Y>R$uQO;&e!S*MTE$(P&dVlYm4nO6*VD zZvC%m{B=uhat4v-Ok}YVKr)ZcomN$Zt3tvXe#8&9^)UdyI}_`Ye@zOJa>pFn z@eTOo3*!2`_)Blk;_S<|v@Dd@@eG=}FfQf{lr z!#w4^H7nnR!{0dibcSG^haHs;U9g{M#l19Wp@ZA5ZKbo4kuow*8+dJL+RS1f8M1)X z5d`bUK54Pq3Dc1Vc)nt)fgXKEkY)Pdm!P0W%m?i!g17s_Cyx8O&k(l9Iv6scUDz+$ z+?U|jDMn8xv-weiIJz<+(A1+r=tYm%z(FnEn)JkxPwJX?hVs3ww)bq6lV@Kc^*(3@ zg}yFIyFfVnbXap^3u#{a>X<76^#qu=hZ}!779ae3fA1e2e)#@l@Z~QrX&H>mOWmcH zXJ4_UKOXR&NqYkSIkdC9y?fxxtbN0Pew{~M=zG%%W}zpZbf1ykD`tDHyxYG^@Pl90 zQYZiS;r?a1NIRhat>gyktUpF8vh~qH8(&rC@h36EO$Li#7Tg8aPk#JPuzbMk>At|q z?AykdOi-6}a4N4!&mzQ+{E)U~{i$QIZ3>efee)U^K-%@YR4&;{Z`uq_`@Cb>xLv4i;<}AQ_L-`6+hVmDNpD=Y(rk@Po8UKM}^AkvW$7ymafY{3?P~;rlKDQqk zf6ldMh)14|h1zKVE|rsX%a3(~x3`z#-nhbz+(9XxMU~@A=-kn|t$&dH=$GUB{!=RF z7v?i?rQ6a1*2w>)X(YCP2CMvs7g^e&HRra9Pa&H*FI3%CjgJ|`8chHh3)sT1Qz?sw zcB|((M?2FoXXY`4MHd?Oli-gHT>0|leFPgD>{`OeimexZ!^2=ijX1AOZ73EIePo$H0cYYZb5{o(|m@ zd^4PSFT<{2M6li<$5%RKZ~%E6LcZkv&n0@fcsAADzRelf&NVIS3q6BE3>+{exd z&Yb1t08e$&ALOeI9r&@4Lb*+7J)cg(o&4O@Q0`e^j{QfPD`siA1MG9r4kBrJOZN7i zUkdX*uXnMh6<)oW?qU$Kv8^(HxVhq@>K(!A(j9v5zkAOG)AQl~{dfNE;kV!aCOUXa z-p4gEyy=7LLYgCs5cyxw_J)AhV0I4co@nPWlU^r2%e)w9&^ur7y1)0CZFhC_^V%>1 zW0mrYN;zxG=u(AZpHVQM*sw*t3QkT^)JexSi`XJ6jpztw{Bo@%QXR;vy;30Fu_k?O z6Z%oxW)kI4?h^t)f(=QBzLokzN38fh)1JjdnJAUk=2P&GFX$WVT-|NXoZtdV+OjNe zq_Y!kwPhMYS;>2$sF-bBAtUb&_IY*O@|^8o`B+|FyS9)^_LSTSL>3@=?Arp;ob%M} z@lIs<5pYCJpB5BsC3mpcLDLL<08)zh7yaT7R#~bY?T^)neEEQ94kEd*pK7R8pZbO% z8-G%BxfprruLhA}YaE#NjK-V?(v#H1dpM^?qLH(3)ZX*Vf6M2>YuPnuV!P*xeUa7q zL|V?T8pr4Vq%k{euP=^=($dc;2@7p5d0zvTfQ>oA=Kvj-nY*C!L{KcRK`R8mML*BAd2x{>}Uce&QF; z;O5KKG%~Fi*G4f)Z2_RhirG0%c`1+nX_fq%zEY){o}~XIZ?%H3C>_t@bgnRf^rn>M znJ0(|p0D1;?%}{VHINmwqpw1&sjXLEtYsb|ZU%I%=)BRxxmo;EsBXQGLr_a1uc(*E zRNkiz&50_1W$}MbNu}jV`;QXZmuBghE|Fw6Fxwbp@iZQz)c^Kp(fPmn!~e>ljigx) z-et2^|DM*;&HtnuOLQERSN$i|@+B=Le<@4bi9c=9KzqSh+bO5>$6{I({%u)lg{F*J zmbsTBn~4Hx`HY=BhHu&~xOjScdd-92d}eWR05=HvX&7Qr)`=gd@TKuOv<_qh@70d9 zvpDH|pk|?eJz-$UdIM!7Kg|cn=F|f-y19( z2HeFpH0OiO(^-BXmfJOP65PYd#g@o?eem&&cLaF^YXo~Y-oEy#nRMkvMkX3%akui$ zp!LDvilB-()n`Mk(++;KU;DaisGKv2DT~jn`ZfWDt?idH`OK1k>IaOB+CiLgyg4j0 zaMZ8nr|_by21Eb8kIe88vv(I5V! z!{7Ude?NVGOF-*wdw=9Ynh8|kAvkH@(C;_UPzURLu2!FoZ8*f$rpl2#2d0b-EjLhg z=hj8Ok5pjbfPS&;z~|~hpPunmds?4g_M+{SsbcGnhtRWmCoXJ5&I!4}qENizbS!65 zu!Mhzm~rCDpsuw*Cj@bX*qlQMx5ay4>gFtLWqfic#D$!8=RRCga~ZqkKX%q`SMCHk z7RhUOJUny?raaVJIV!>Ng6vD!>vptw@fmcuWqKUEi;w^FP%)u;sc)fhW=GcKQH%QS&{zSGu zLNCUC%By(eAAxleI^K@HG+@{JENq?^)xJ?nxr>|LSiZ9POwKH5Zl-Kw{0!s=o_3DB z3X{#3zB5`L>Yqo~py`n>8ls1ypDN>pI(wM=C^PhCp#W%}BHr+7(mpNNsV5|$a zj-OSj^o6ELo+I`n|9~yi*Q9+@jT$BRgqD<*EqzO4?PAr_1;J{_yk>1kTX0^y@HIub z-s(9!m~KcQpYyWovA*rxuT0O+z875iq)h_IIFO%Os28A~xwA;xon_k!TYrmc5IMfd zCvnXNrm3f_^G8RpkEKWvd;=DHitZDBtMOM&AzK5d+$Je3P^` zK7N_L^$FIOF51NlGG$Pr%N4(+yT#iWL&Ml5Wrd^Mg?--kzVCf28hfpR^yBImkMLhM z5vIRZusVe5G^a-UaR^aRBhZyyVfR@8gN=q~^5JRu7}o+0op{wt!B<`R+@b-k6RPqU z`1+wByKa3iTZ06h^XY*Jgka2iuhO~`W`KYp=#0FxmBVu1o0fX&ZkAExp)_GZJ4>Bj zGnT>6voGMsa8WPV)n6VQ+AKR0wC)Rc9R}DEzQ-5%o`ON815{ht-r!d!@EH?1^p?$W z;Y^x^-Dikzu6qmJI(Hb=&!AH}`9`}J0NRED``|CSFktWRw28LS?Aq503-fgr+a_q| zFeX*aytak33xjr>_v(rxY*%O$ia)gUB|-Z81=Cz0$&mI=lL z&oEB8GJqeulJ6Z6X@jE73-%g{H(+|7-@`moVtw=ng0D=-(BJ~zj(bRGgTWiQz6R3K zuf$*PDi4eCJ2$0N+LX;kgnsEZ#X_T=GUmEPakGv2%x|2f)Lqin zD(~pCPYe6}r2%46)#WX)d|%i1);7P_y%%U}jBpI-by$uvc=@U*+B-ZPH>@V5t-llO zR5pW8+Fx?PI(!)?c~58hjG&G=;YxboXMOpSiW zGv6WK-e0AD)EL+@^~LL(^ys>Srq1%xr@A?mF`6$((NMnjH{=aMyL=guJ-e_ zLULvH3@vk2y^NK8)-TJASi3aNS3i@t)9U zQC42@?Q@Cd4k-OKU+{Z&DlF zNn0M2^$heLl*valB8BtH#-0TBN$@Qn!RFdedaK_z|5gq@`A&@)pt2qza#Cig@ss|P zm;pbXHd#ZT2v(=@Fq!nXz}_GdjC5h!a_RWoOsH)#lE4`DT_*GqKBo%ke<+eYmt)b6 zf+W3nU<>n+-GPEb;+WaFQ4A)VXRpkHGC_uch*y;U>XWZ`>ICH%#_kC|o_+q7fbWj{ zA_6}clJ>>)S(qqoPpySSekoh}0P5x-<=Wm{%9M3!fqhb9D!Bb+2`4tDhXjdsTyf&m zq;IbY(g@VN4gT)d+u%1@s9YqKqq?Ds^55O(R`~s+gZ1(7c;AU@WPW+|+xL~pcJd1y z%BT&F!Evt0EK``s11x*YVDlZ?(wQL6V|-$Mo7(36GMEhrTo3O#*Oor$Z?GC?g{CqH z$~3p<^PCkmo()p1^PI;4u$iy3l9n>4vlG&H=V9S^;OU_fiX^OBBKn;gIuTxm%oVw!^BZOCK)&OQenZLh0qGMU?g+7t@^>CYAs#MWO*gBtBhr_R@qLry#-!v9 zo49G|KXAMdq{M0M8UoUA9&?uSo8sQRVdjf}Fk_^(x?F>!Kb`~_3(kFHz;fw$Y&NL^ z8@~Ce6JMM8>suM;dzxu?%$u@Elnh;X2)RI_Z>@0t=p#(-H2dD_Ua;EGn7-}lBj$oU zu9mgLsiJd`eJ`K+!35v4TRBA4ujPrv@}^ilVs}9N=tNoc^F!V_B5R3ZXf`rbplzis zCcRTUQvK+Yt+9V)=G@(jLi_mTaDRE53oyS_m*-d2M;!d#IYZmd5jmx^Y$j`kP*($1 zU(se+gJ});8NE|cRvoM0oz<%LM)Snj3Rhv2}8!{S@-3 z4%Ub!RVKdu?YYrQyr<`fbhH87lqFa-fab`Tk)YijRu0gdJlt6{V9k3}=__TEg;*0@ zd462)3%!5rV-}AOI5RS;dwz!0UqgvyYY!#pVyk8j@=iLrx)KxHUC+z9H7$D1ppbt8 z5$Rh1z1pC53Z6KAs8DBrbt}y&@8m_&_R+vJ%F%$j6U)6p zI{I2~pIYW&d;89_jFlyP?Z5OHXKa@M(==_KR=*nLC7AHJC~&3g8w_$6fPv*}+r+V* zLDsZMULG8#N1l|!OS{OY(g3zKm3G+9Bp-d_2u)iq9dT2nsa1`SvbumoZyg65$7h1< zMXzHM;GcM=l|h=46ijRD^pmYPTi5c=8J5wUV~v$ktxVYF`s!U8$-~0>2|V%`j%AA8 zcJ(KpH}=ba*cAJ>P5E41ybB-Hi?2js<%!i{fn#EUh1dz1=4-m^W#0i;5F} zLMgvEl{*vq2mTda)H(k;kLHe72-ui8#M|cX)G&;bgF?jqdS>2khgI;l?kp z(X2B`ELM+*GFJT^&RNJ-v7S@nz==<1QmDbCEh_K(oAB>YFi zbI0xC0JhYza$9sY$_0RQgB)RBtH8@>5wB4E3h2bzYknLhCDWb>cK0mDDUVYw zg0*q9W^G_W&w#&@rGnMF9hXidI}?(-5!)9$YN{L+s@ zdMerN55AG^cHFRMJiJ_Iv? zf;^W_1`#f@;(q${>G1L6$HNaCFW&6{*Pr8b5%u@*^cJQJb`Qcs z!WIOECnKx8`5a}&2lTJx3gNe@P;C2ei42&~9}AJyKILqc^PRBS$-+zcTYtjoZ5Vr; zL&pB9+xy*=d3HxMKiXm1IT~%O4$e^lV0_j&)Vci$`EE0xX}$(!j7`S|d1k1nQU8>` z!D{*L!ETO2-USTGFI2FUw)EPxig1!{0p{s zE}B;s`r`dN-8o~Mvw~&(K_l<&x@7D!PY|HF-sEur#~8GO!_o2Dv@r7M&&pH}bI+T! zc;q}R^^rb(aPDpiV%R3OAfNR>I-qz#T3=FL+tt3|30{5`OM0AN)R{RVKgs<-pHVMv zE`YToB>Zui$Croj^cU0AfhiPv#vih!k#a2mv%O1lC2RfYy@$xY%BTO+cD1Wb6xoX- z$4{~WlQvbvAw4z~_WXu_YSH_GsC>_F#*OFcr>URzdpOSvUzB;}U=d7vfzq>UzgGo{ zy60t`eIGhg*5;dh17o+WH9k7A>O6I4RRZMXm1i>@w3JEPPLZ$!)!dLxX(%*bng|g_ z?Nk>CL6p5fdmMQ#5~0zn+%?f`+$fLhG|yDkHvHS@+SZxnRG@%H^qqSarCTAT{9^jL z5n)e9z8N6mXoNl3oXJgFYLdQJ({gYrtPZ6~V>4EAc;16$y-J^5(^IfMqeiss=2a)` zbA1D2>V$L>hq~K$%Xxy!q|)b<44^wepZs=^D3HspApZlC~Rs|LH@}nSng=9yOf5ny0L98ut@l7 zuG)b%$dk5e34TZ_hYMozFpE_M#|oI?PrIeNcFQjRoj(R)aNM^qMlMns46x6&lm0*b z?tGS=P;drsHK&0+pgd$$m2~cW#Ab|HXsoKOO?GcBqi~S}(47la``{~%K<7caZ ze$-#;(H8bYD-vMfQzBS2_TGcI@fF7gpf4n#STJn{Z_Wd08+*I>sgtD*)V%OkImcHP z*JxUxH)*Tj(&zSKCm-{HgQ<)VRnNnX=G*pPwYtNwz5PZ-GhtCRZdXR7bLFn5fi z*SvGp`PfwFaL(xKFIVO@mIQd>=}&o_O1q#(wV*s^!)9i+6TbMKIRnX|Wq{s!A;1`H zN_|?cPuXWzmju?Sga37(6BjR!D#VV?mE{!^*xvpD&(Qb*Uj7!ri}qj)dKb*O-mwwi zqLGhnc?a$Z8)&!e3Ze@$Rqm`Ntv@Iv?PBBH(w1TSVbf*7X}=fFakf0TUSKUFY=AYW zs*e?p2z&dTo;$w`Y5PuDl)vM?8#&Te71eU?+^;RuwqT~dFP)stBUgHR;l@6KMbab@ z3rKIRN!fUF6HLZ{^3>k0yU4tVDZl0B+*!6>&~GlD9v@yaDF?lso&lXff#Xqwcp>hh zY^UDbygR)6@E)Qw>2(3{YPPggyyt=nuB5Q4Hz0-07(O#1ox4llzg7- zOIj?VOs+DrZ5%1|RzDOeFl_AW24KZIfn8Rs#<7wsZfGaz*#w7^S!6xxbP7{8=V5Z5 z2R5PkmwsuT|Kk@^my%?5XJ9#|;NZ~z5;TI|;Hd$n&h6t7-lCev6UOhHh{oaNpNlTi z2BQllIJFHEGV~j)8W_8S$|6C~*+7!ulL_k?IVOPB|1a(liABMO_VcSj(qKf|UOHKD z;N@98>|4Jjf8?uf`b)=`cFTlMn;H1}k2vN>x7Oj`OyXm=_+OH0W1IGQ?FV&e*xi0h z7HL#IW1|y<($FSeYZVi^I-qwhK+w%D$zn$PECK{KK3AOylTQ{F=>qPMD33XVa23ky zfvjXpA1`0l%Waq#+`^9%N)tqbYrPoMf6_Wk4G z)5p8R=g*%HpFaISnLgrTiw^Qy^62l%+deP|w?EcoC?g>Lp@9}S_vLO!K9W7sGL;=l zf*A9*3ZAl4nKWm+D+{RhSvH;ih%YQXGe_lCU-1gsR$OFw1t^Ot- z>FssggHrBc8zU6&n{=~6c__q|TiW)LFiFue*C}9&z6Pi^7~2nwZG@>aUpt-R4#fT= z?1Ikm9Rqk9VUq&2?B&X!NFA_mgrqH}T=;zp9j@M#vC#jXL&yQOu?}h-B-t%o`6nU)t1`T zvvzpN&Z<9k>i0_g#=Y}o-rS;3GyD`M8xB|R*N&$15sjD=(+7N!M4!6(c z#Xg$nr0p5MoaW9s$mx@;4P+yuf3de^rAblg2akSv^w%}TSak#hdT(~4G^mS#XBP)w zL6wD#`WF{5&vf9s+Yg5izx?j-%U}NLaFySl*Q=ohSs8T@Rgn!gj}(@Y6s>U;I3`WG z$mninF;WsruJa`G1+>$uD5njg@UCE=K0*9O$j;b;JuUUNL$u!n9RURJ7S&sj){8`) zq9EP3BztQhyajt&LULzi@|Zznjj|7%*yzV#hnGcQvL;u$Y)^T=1>zmaEqwA?LV46( zM|T2F)he@*&FXh8ABY{u?)%KiwF|kf?*Nn=dFn*>u>k|vSI*kU#}pFGI*~s!seR8F zA;`*)DHyEcs|K|4%A*naTW9$8;;6DKOyz9A*hf8_9M(iIvPWj}PBdg2v^o($gDYg` zirR}r{`jZ;Ww8dx_<;YN=+(u;h7%m(Ol=ET_k`X)r|t912H$yv#Gjf4H^CL{9+@)a zs2<8uT2AOLF4eMjcXy<6|Kk0J^_sEXx=&w%lbvXIYD;-|0g_)7dw+Yl$gA1f6sk_%p%#Ifs*}bO#oT zul&+-F~|iH83VGnn$_Q0lMxW10F%^JI*Tp$a6wwQ=5|el3882Pfn{Sy z!SvW^Xl-B?7Y<*JeSL-=g;|$L_Z3Ibm@*4zL&YQ|t}I7;)>ddpN7L^Ku#Y_2H{vk= z(kK_BRxA-B(;9oi=u`dhGwmR9{uWIr>~%;R{=DP#jL@Y3P`=SKh|vGG@)RSV{}*1` zA`5Blpg!tlpxQei@@(MyC=RyvwST_w-@8ES;m@E395>idv$fXS-Le1NBaWdRKPg#4n;Qjy%$3Q*Pcyf;fiUVMFg77T+g;W%pLK2`NaC43(m#A& z)eF@->KO%AXqCg`J@dAA)sX4o@nMU51n<~s!|^|`usHNmi(Cd?Ke7hf?tG2j`|?}$ zf@+U0Le+%-&W;7`Ev|J-D(z~&M#`26T{HN@2gLW2ztHorzmE8(GCl-1(g10e{VKNv zy4gGoO-|V~qOC4RK{&Nh&hdO51_(F(BY0a$VbODbmH+5x;l(jU$d{UR}K z-MgwCbBmRQg4)nJ!epp_OO2NMi2WZ-&hY_3c{jw z;l<&359Yo$`eS|hriuRyPQ2i~_@ zp%}@6f7(XBkxqHk_7Np=4{UTj#n;xHF8-2IP|pOZ3Tg91Je1Lrvxl8md<^I=y zO-ug@|IQAVd=RSrW*-`$CCT5hb$(8iUKsxoe|*8`A(bF~YGY2evG-^E?ZMmZPsn~! zBP~nNE!`ADNwr{|&zU#)@Ini2j#1hPC(w9$VNTOO z9WUNx$t?E51)d&Q?;P2s?YQ&ErbWu~KY#8kuhQCnaMlqhLH>E@%e@V6KAV3Mq^-ZY zmHwyPk8Q3KjQNO|>*F=kKxugQOZo58H(n%D_Q)KEzddjf?qd=@5;4K5_HnL}{^q~H z74uhPA)nucrG6D(5u#9&fU5P&zDJ1N0qNQw;~RU3PH`-$fs^m%)R*?SUiie%DYK0* z^twx0UNvX!XUvcQ5ZK}e=Q2*ml~FmRRav$jdOqnr@{x~X&&o9y7bAylszc?@nkIg9 zfv;<^eu*sgX6bT_01IsE^=-zZia`J3Klq#fXOr16aPr=mGEw-=QL`erz~~~C!oSj!E zUX8A- z+1H@?j$3haD}6mTY@PD@ESS#%%U>UJvUM`b)%&7vU08B{B>3&~t;k4T$&@ue+ZVq0 zVdSW9dj%{#7ZLkAGI35&?aPW*o3vwbdva%)wB!H&^XI@^=#RVtxrZy z`Y*4TNjPc(>Kd5dx#A5 zOTLIgdfKUv=aU0f=fcHf+H2pY`4>O8Z}bK8<*)B_2kDf*V6y?~4d~v^q2sR&Jhhp6 z6z3cotl1}mc%>In7HMm}Rl0Fj<^?my-(tRL(EzcJNzvHcK zTjjaJC@6&~v)&n#elbNpGnr>mgI7pk1LRAZ$l={8!v%4CEuks>2T4k}8r=%ubtUcSS_-ErTO?f5ld6_nXS8>BD!T%vDpWh-N4 zZ@*BBuvwGaT~>E2@8AlfVV1zqA2{jL1@g?hS>2pKMtKc%3?UEghF0l8$4S_M#-Dh( zvxO0y*R_YNV$-10j*NH%q4T9Ul($&9`~jkf?D}WlQrERsIK~d6m%Lvthz~V*t2zc^ zTl$*v;39MVvS?^obm(O>=kNcmzZHryup_o-5ok3N>+QZ(AGdc^A-c8OQlhK6^OP)4tu&pY}r1U!gHDi{!w*{kN2#=tX&6>b&4>Yn;N@Fr377%^DooAo99?yDt3`rCPYh) z^|sZ2oe*CgC(?<%oFvNGqc!E*bG8Io-X1g1^Z8vL ziLi|UlmV_gmI*MC%QgvCA?w2D_;;+^pLtt@I~~}uV}L(s$gy*Xbk;&qF|xC(Y21Ys zq}S)j6aWO;xwv?H-!EC+J$&W@z+br`Bvtm zP$n%YUHfQRId#&rT$<%8V?_juMpHNCo{#=d+1zSdZPmND&Wyw96!xW3+Gxv%;4OIz zc(}VT3-&m=Yx)8Do_Au#?y;r5NATqE7S^&?uu!vmn=yX5r!b%_24f8rx4B7v>UC6e zgIt^}IY&Ohk_4;3l%LFXJ2>jkI8aX$w9(JzImw~>7U1F0-#H=kR^|$HxM&dL#R%kp zuE85SNV=QKP|<@J|L(M|3t6h~MdZ);wGpj;<=9#}hLC+Kk12EPBD3?^`caVS`vL7S z*{xo=Z1VD$SitIh@lBktE`9I*dhKD*>gJa_+fH*{{9kgR^6vT)yQ4o1eXSGI1)?)| zFn2LsWKJ^Zek5~$f0sE(*_26Wuv)L)2djfKc)~vY1wg=9d-ObSySK+4{AEY$_A(ve zYy4}Qf#KyRd=^^qr;V092kRCs#S1O)$(i?sA zpLBGbG^dfO7egxpT>OK-^&bY$!fP!`=eWz7ZxO;cj>AVMY7lDB%HYwf5h(8$b)kZh zS3ly0z67buV9|qOk1k+VIce3|9ZZ!dS4IqK7r49vfq^H!uqg_v&kW@~nB<>aL?M{h zAC+-sBokh7HqL8nUzD7s3ju4LaBbTwjF=-hl~w-gR2k)OU9nC}44l18K8t9rRL2seP23c~f7?QWo+`HlRr2`wLd>JWlwYt;LIjY|l^{h-o z^Jq=vJ(+B7XuBp~Xs18;bKbXQE)a_tG0`9tv_Z;c?3g$0j<+~Du%*>uzvznMKhJ3o zCEsVvr@Y~%eyLeO9)~Q{@qvZo{>}ijZ&}D#2S2-)e(;5t{6Yf@I;vhxR>M`eRoA2+C+ z)rGl{ww~qHT@C7_7pj^ETevD)7*VvjDTrI|tPt zm1(sl?}G1Q@1McV7HE*4K+lslD*`dDlzBY}J< zSrLGG{J-@hS9BqXHG(?W19OLRXb^4)n1Br+FVedhZ>b z%O~QA`jNNgZA!Fo;1WC+uMe*T!>{iS&kyL!T;rFlUc3Vkev=@~0cf`+ z^DN-8xhd#mLbKc}a2sQXjY-bSaRlh(FbThbQls3qgR^)!!)s@0cM|RZ@s%Fk`L-$l zs0)AdI=9_m|I8#KP2a!gtf=7V6Pc~_Vnsh#vPmQZ*;G$yZoRh9ZpWX7Lq3r5Wr!Bg zMjmY!|FMqpzDmZ6S!c*-A*6IkSmA2wNp0WXxO-sHveDidW&gpsO) zG`LvG@FoDYy*oIWxGZb)>ZrXJsHZYiHf49w>BKi6ue2u-)t6ZX^)xA8$CIEokz)t- zfdMf_2Jk}PGYQVN%$Q0o^yNu9XneBa%0K77(8-?@k+$GajRn1%VXfn_xYoOjNc4$` zFJDgLgH>tK3tZhz#-&wl(x*&RkM}?1>?HSicTWKODeqg==UpHZ6wuzWZ_wHwXo#?} zbGWzz3-0q(A3M;0{25}AY@atD=(D6VX>xd%$k&ryV@pkC8`YDij~i&>?g-mXA0d!t zE^C0Ok8)N8<+Cjx-}M-|6j&t%Y1eP3ibx`Q3y!J)YMhX__Wo|A3@VjYnOZS$eonBy#dagg!QEA zFt&}@HlvO8mUX>MTIWb9_anBDg+C?y zk3dI=ZNCa{)KQdJAmWp#8lm%qf298?H$S{4KQQU^Gvn-pO=#uxRp^(JL5d(v+NHTB zTD9rMC`XD8z_F6LNLR^&wXm`d67t+EU#yV9wnNPbdpmNLJT zCbD`j(F18iALM%nHj#mV;Vv)VH;KH)UiO2v_Lr_P5YDkX=T)wreo1!F?4!uI=!Z_u zEz^dXua;oSX;7azdyON_ykD*WdiVV0XFU7IrM3L6(pm$w5P?PrA@vC1 zp(9As^pnA=c%LRM)sh_rX%ywVUIi}P;7;Lul$vJ)75_$ zF33Zd0(?sOKp|^KY8%f?zSzUI`jm2-j=yk@-I>VrNz25E&(SiwsSL63UG3_R;9bAZ zIkadyv<>_y3dH`Ay#;McdE^q1d&!&}SqHXfLE48rEN{j-($+}>eu7zLAE-?{Br0tu zH_l6jw_w}pFwLj8aR5&HcJY^#K=akxz^xnlX~*9ZF?!`2yeYAq){G6mt*amOVpqgo z_#Q#IrQofjyTjA{@!k&bgx$dJRU%!c#g1K-Gi4oco}k zepR2cqdhy`JC`or%ACg_#^36@Gs*X2r+0}|bjEk*LBH(RpxHJ9UOZn>mR&JE+9)Px z&VL~wEQP}Am4Lkc?5e}(m0&gfN&E0s9r6yDZ494)`YDfuY@-f?r~NvXv!G_RU3HB} zHqgIw5rSOWd+c+hWnb2o&9zS1US5X(DRk~@AD)AB#y9??pu9f^-r zJ%y~jobyG^*uuab>ky;^cSo(@o(+jD*%%8vjJVq*7B}*Hn0E2Z)lca z$?3&l(C3HK#9qN4GoSc)1Z#vJ>>OK5Xaha7eQ@jt$AJH-BcTr*L5lhya}V>HUy{Af z`8vC-S2xV{vf$%b_QLK7e|u7Y`sd;9j`2Nn3v}@FnVXzPZlL2Dtj)CY#+kB_Z}S<> z@z0c^CkACjXomV3C*?!hESXJBGOs@8sUi8xJZ&kskA{BYT0n8vs)BSK?|Z9AbG_L- zF_18itFUtAqBwoF%BBz7dDb22i!nY?e04vzPoTfj;%SSliyBPGIzfYqQG&KtAu>=) zwQVzpNy{3}7yq|^@Bd`{R>M+idJ6;qJIh^38|J4!ZJ7mbggs8O8lV#|X`DE^N^=RI zbBUK$;^QEj(VUPeE1&h;8^Vmza|jWiKiiLDb0pB?JWi~0xzL6wCuQ-k#-WI_sTiYH zkIdrKp**M?dTCtTv@xHe)sAC2SDcbqfeQ%T9j0j6aBC|i@xq35{GqlQC_VU+9@(6{ zBLk4%)5jnQ1Xg{60`uCb{3KwxePyt&Oxi2XLA}$54cazFgC7$ogWtx_zOyhW2BRb- zOM&fG-LmeI8~7S@)0ZV9qW?)3-)z26Lt^WzkaP$w`U|v2gOMnZGTZA*+AvfXy0WEz zq(`|Ekh|{MU3?LxmD@gm&Gqm44MZ}i>{IEMp2hj6(;Xz=#&T6dfcV#ofrE59B?J2sG}w^S7r*k531SGmWBIonn~X0)YE zq+=pMH1sO3zFqp#wT-VDdVcLf+kb#f!O43wmwzoW0R2}wD+?U!hHvFcnw09evnxnX z-Y%fp$+qROBM79n&8sW_W^uB_v4Prco1j*}e!F}3A&K8~k937lM1uJcbp_7!)s{uC(hPX?>#qs=yOo&?{bti_HicoJT) zHj<{Zh&gGe?}@8zr9~n9^2IDZz0=W)H}gJzkqfg-LfDYNP`M_s?LXwSevN@`?ggY_ z3JU~Bbn~{Co^#oLoE0jAbQ~hr*PUa%AiTxTuip2zx&e2_6E8pls z0LxgHHmyUu*6J6FC?Mcf=LL%IT24Y)u~K9cMy}|A0!W%Nb=!k)ZRkaoRHlwI!K&C< zr&A(AQv)sIFZKjCn6*<(zu+O8Wudl8#Br77AXs0bN=jnXp_duTkM=D@hwv-k^F!Os zF}RIqLN0ulm|7i><%-_x|1gJ$+YU6MTe7Cvcs=0Y&qv#}RT1HE47k zlceRpP%Sdxf4kFfnElzgAJVPWf)=jfo4@{==J2gK$NCeSQLl?K6Gp+ozRz3L0rMI zxHE|yq_e1#aDj=8d>q)ZF`s4OBS=I%+Bvu83~O~!25I<8F&BlgU1SI3lb7=X>y-M) z`=I>Tgna08bg&^ybX+u)*LpsW*9Jc+%~_{PT|~5fYh`6$3Rx8S7^vh0()5Ru$jz<0 z_PscX+{!F}A3nloA|tkS@Y%oVW9expQTd3Ig~fG_$)~TKY9L&nHHfyYyDvOjC*yAjEConjk-@-A^ zVT6``=B(XzJhe;h)0}n1tnUXHLj%Pwrl1}6Fgd3<(+QL~&(6H_Xl$n#fTR=RQf6SO zo%%x`?JxcI<=IzObsXC#9UrfUhr5TvryoA%63fU+$(>fx{!qfLoX8-ua%vyJa;c=Agf0CI z`l?VLQ%~D1Rlv2Ba}1lm^y@i!hSMq6jTf`%p6PIaV}dt{%ppqx+GYU|5&_7KlH&*rbZV`90Tvf2)4 z-AcB~O)fS*UWNz7Z!Z21|Lgx1^>(bc)ZE#u6CZ=K?tpb6H+_>^+UKC4r-utqJJLl& z!_34Ug-Pc}1~>$H2-eBVvxoH#fLRPi$t+BaB6U~p(P5O9zWlS(%BRm>*cm9T0a!eJ z?&OyAYQSNd^CFR8jW$Euv|y)3K4~ithc%<$$he2qG?Q_6D8C$tLtg>r8LbU$7#)tb zlF!&XJgKyg95m9(l^{TEc!k-KMbZfXOxni&N}#tprUCS|f!QZ_JnT?w!Lh%ztK7N+ zXSsIjm2L2l!b0nnUs?u@*9NNBoL9a)z$fh^3DV_XbadBDwvPrr29oj71(Z8r`|@Z5 z(y>)v31vV$h)z;>cXynh^6I17P<=Yk1j`0&pGo)(2B(2f?ckB%JNirzd!1(>9TO2s z+o-3D0%>{HngEFg%Cya-Sb6q7CGGIxoYz93v;0+I&@@exP1p##V;LqX#A#s-T_JdhuinyU>WVFcat`7b%C+oATqM5EI#P%zWc||v6r;_I;|e< zJH_rCqs;n;3(CPA)s(lNEt2M=UB?1E0k+=V+luH5|6B+|)IOX=$oVR|#MjoCg`8tX zygqA*KI;(XETZZ7J7@de{K%{?`{;nWyVI2h0ni^cK+#gjNf`V791iFk^9e z#x4p2c-s5+CKo(uLcT$o?FS|p`2uXe3o!nqkhyEo%9!{H-I>!A-P`jSp5F+u`B#Ef zbrZ`;`?^{->6?ENekh{~f~O~=p3)5KkBeL470mP$9@ ztaqO19G3ZSwe_uv(G}$OEsdh%rg32MQtm}%!TH3TweHb64-3H`8t9{*<`Vmv5#W`( z4xYhv&KX;n_elTkj*&yZ5;wZ7vb<`Mw03OFL}AIDq`P@p9nx0*mSK~Nf9K!)Ux*r* zjuc6ybqG6p7GWLZlB*Lfpt+^5kb-B09KoeCbqX0LPI9r65BT{>F4E#>(&pUimOZg} zNY}%(5V|8Z=)-3^O1UkY#op4=)+vyax{>2ucJB(7jT}=yavTAJU*4d81VUWEufyX@0 zgoo6zIjgq=);3Hh&{~1*nmFuNcU6_Iw`}W&J~!1{EKbnZ@u9v1+92sT$UMtqd_%V3 znKXREt3Yw^Gud0Lu)szK+}MDRfA)P4HA{2I*KK(Xbq+PCl8M&8Wbua&q#)jLEIGkuVq9b(y}{rJnJ7JPTz7~8WTxsJK^{zVfze>M_NYyq?6om{ z;4J{{shkF$p8bX==UJ@0ZEbMq?qz?cz859A9enj3yQz#E>H~SC1p2r^K>4$%5)40$ z%_vjO;DTs6KkG``3HjaayTfgM9m^NBYcvV1K1GfPgH>og=lR&>BLq?QweSD+DF}DU zoJ0-2?LFIRV{L12oeqa|E~>$MdD7R*BRkFD$6wON;O5XC5QxgHoAEwAs7@Frd3S>h zRP|+Fy<^!G_L_M`UQr%e7kU0oMLmvyB*cf{0s50X2f}ms_e7px&%RQR!KF?c^s$H~ zH@bRjcvUm_;o+Zl6Q8<@rf=9!BqOi-X(x2q1<^-0tfcJxj`R zD;Yb}F1P;uLKbcNMH_uaiuFnR!Fkp>KqT|=yEuWZjxuV~bBLXH=>d8lvAmG04R2I; zRljG=^1CapK~Kt=`H49Ler|3Us2VIjJ}Ot7CErci%d-J?v^aJlJ9Uvcb&i2$5d7fO{u|@b<1)fKMGI_YcA^oduT<8zOYkZEnH$V*QyOxh{ z)A!`Fj*xSXosBH@i;l>p|9GCVJxtzn?{0Sdz164TsSL4?BL?@1{KC@VfB855XZmI) z!qA{WPY!&`Z~!X0L*_u`nuXv)1C8LGvv5m50rzJhim1>^OK%jJ*~QKfhNj?Ix*i(E zv&v-MSa@UP(lDSVi3a1a*4G(|>kfvW>G*8*r$lHF85>YwxjKw-!_RY>B)!(K$Y5=F z6@7!Wp{)r|LU!Ib`Yk$O@lij^JFguHRYLkfy~T-hRwrv|O_?+(r=*Ka7r6W!rh+Zr z1CqZ+0cnS)G}O%$bSyJJ`gihxKD<-1{%!UNgEFZ+$45GDZ`_?iFn~zT_*)^fxc|^o{ryG%m0Dr6uLmCsT)9F@-WAi~SF)ypHO^JPVpSIezT*$Of)o zMyZcDFIE2ptM)lZeFIXo&7%sDvwcZwE06!A3#pKB+W4<$q(vXA93%4X*>b<|Wl;V3 z^XELz`*3%kG2SoFKntwUT4{O@yGk?UkAN&VVbFrkp^a7|wyWQjlK&D=TNZlICaZ02 zqmQRGS@kSnE5?je;wP2_KM5K;ZcTI0IJcnrTq)OEfKb|B`Pyim%v0V|FFv<%Dt_8% zzse{W62Ew1WFN^}9Lovd{Zg8i^Gll*w{;P6O9NI;(f*ED8nwc8!qiW}(Jr;`G+L!U z0_YffFNa?LBR^-~6cK4O4zx3tIp+&`OHSK+OI$=fKJBS%y>@%edrF;Wz0GfV%*8>m zv*N~Gy9(V^r4A?A&k6d!ym6*r51-6UoHOPm{^4B{FK`Xg<()5!Wj;|a>2_1W3zf{{Fp+ljmw#-bzv;iNC!shg zpL0^#G^q~aw4M2mvB{T2+dSvXkIHHt1%k~v9kb2ZR-CR0?RAc5RKj_QOQ&QnuH{(4~?YtBl$p7E?pZ@DdnO4P| zC7O?hAf2ciVlT{~>AVFoGI^&KX^qedtOZBlJq*q$=UJsgYt>~jTao*A*4c9fUD|4` zjOkFhICBc>Y(0lq7KgS~%5EKPZqZ48mWww*pjSvNjiRKTbph;7D#cW$C12g0#DDelRi*!zPYx0N7pCr+g_U-`sw@r_8}5 zmNxgDdcIA79EJK#J}~n&Z2DLx)G)WE_Nb19TNf`rzOqU}bAcm0`>y`lU`*K!Vtm2A zWy+afjA3HTfVL^L;tS9od?)j2hkp|_p+LS*DcQ>?A>Wkwspjp*pmZVzL?vcy##eD zHVGeSXeW2&`#4W&d8O|+h{IF+LZdq-?v(l>a26+yTc1-4A84Vs-;|F|ka4^@mh?dv zRc-7JX(mUxsFSu*cQ8yUQyx=+=Hts;@fi`W=!{4Gr{)*D3lvkx<-N#~uRoK-Tu z>cw;T1N516P5_+j(uAn3Ry`u6`&vwWEfL#Oanspc_SSM}6H@rXtMsrPe<{ma;$a}Q z{4TO#T}u1R4I>QVc}zgCp| zbcy|OEFb%Fqa84sGC@xmR&yDp(*sd5dhn>coAyS$!c+B%O9UkiNc!Ot}ETj`lOTtRrdT7}d|) zV$m!}(PkS2$pU35&+0)M9vQdxKQ;RN*kz8)shnM_X8cnSpNwk&``|cs-uOF?w5$aj z_=n>$A z;xu2>5Vmq5$>z1^=EQ(9MsVA!zw%PA++sz3^6jW2D0|NEv3YEZ%qgd!&%bh}T>=jS zdHQXbAw_8JE(ZIBWZ=CaF{SLZLKpYAD^b!5VM*yI4Z{Yb5 z-*G|LcgCN_mju%uQ|=*{_fSX6lz%{J-*Gs=-0916K^Z5hPQTMQleaquF3k6z?+?$9 zJ|kP*a+?`enJ}SmUpm>0O)bxDd-A!}z8-n#0DwS$zizz0xZ*8s?bF>OWl~;$f1FT` zeDzS;=weCqQ#J!>X)Ei}%>aQm!3C$k?7{&~7LJli8_V)bP?50{zF&f>{q1|?R9^e* znh*iqT=VT4xfrZUFO#b!@baU6zTPM-@FlxK*(|@fqMi?uhsKS5p`0K&3=*imyE)wW zj>T*G=l%Q0fjH5_i;xE{TC`U#E-mJ$Z<7GeDYz4{i~R-aqEO zkly~k^ZDOAvH-3ISWr%OnVfdzQvncqQ$YQ$j0UmWO&%R!tjL=@drcn3*~7sOaV(#Lf2<1Fgs_~D%K;}1jR;t%=AKQRwyPK0jW`5|v) za|Dxt7C6?(#(-S@%1&J#H5mSjeII!O9iAQI^25fGqit6Ch5IFpE}(#GP7z*iv5hp- zr?uZ(P?@@Z_`?vkHywUvIP1>?sRJx=Bsg~!ylD4LDa~ij0hB3YSvm-mJGGRhPk`8N zLFe(A&sRNdt{mUcwPgMeG+1p}^<4Z@R*=@kU;k_WZC8R2cY$&DD?5EEjZ*1o)folX zpm6Zm#!k0Wbi6QKZRU`j#xQW*mwTi$cc9YJleUL>k5M`g9m7L+p9yDgoIOOj#Uq`G z4CV#%rVZ{ccY&ucvV|w;x$4=2S=xh?v_XZO?XE0-;s|NqoQ{&`Ka!(3wk?_Ln5?qG zQOLv}78P#o*1&*?`=ZFo+XSdIOTM%A0%h~QX5b!Mrv|qGxESa=z=zHe# z=mpQJ+o?%S1CTE41`Y(N-g;qnd`BR0`|e!=R-ZSuUpyR$f=+6`PX@KK5wdG$QCyjic3AFocjy|kUmzFR)d6vbx z*gpY2X!|wkB1j1*SGJ3>#yWFrs|XWr(cDTzd>hj;mZy}X4R67*{NAeiLy@fl-mVBcDm9WWF8`O~4R zc_4wM1Zl1xBoD^%OvS}#Q((6x($$79<)MWwm|a2B>a=ne^gpLrIKy*6+xXvua{e-| zE<5*or{4fX8~Z%+kTr<#OG$l%2p_H+)E=yb^1xj64`fo#zV2!fSP(yx*Ya6- zB+f?KP8h$U!_W+Z)vtkrYblst9z`Q)8r8A>Z3F*!p+iIj1{ur+as`C~b7GyW7LdHMr+I`)+TIs}*x=c>�>yb%TV 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 + +# 驱动概述 + +- DC 是一个显示控制器,主要完成将 CPU/GPU/VPU 处理后的图像数据,按照 Display 协议处理后送给 DP PHY 接入显示器。E2000 下 DC 主要有以下特性 + +1. 支持两路Display,两路Display相互独立 +2. 支持的 size 有 640×480、800×600、1024×768、1152×864、1280×720、1280×960、1366×768、1440×900、1600×90、1920×1080,最大帧率为 2.7G/(size*32) +3. 支持AHB配置寄存器 +4. 支持Hsync,Vsync配置 +5. 输出支持像素格式:RGB2101010,RGB888,RGB666,RGB555 +6. 输入图像格式:ARGB2101010,A/XRGB8888,A/XRGB1555,A/XRGB4444,RGB565;YUV422(YUY2,UYVY,NV16);YUV420(YUY2(P010)YV12,NV12,NV21) + +当前Media 驱动控制器主要为用户提供了以下功能接口 + +1. DC,DP 控制器状态初始化函数 +2. 中断接口 +3. 热插拔检测处理接口 +4. 多屏模式处理接口 + + +## 驱动功能 + +驱动组成由以下所示 : + +. +├── fdc.c +├── fdc.h +├── fdc_static.c +├── fdc_hw.c +├── fdc_hw.h +├── fdc_g.c +├── fdc_common_hw.c +├── fdc_common_hw.c +├── fdp.c +├── fdp.h +├── fdp_static.c +├── fdp_phy.c +├── fdp_phy.h +├── fdp_hq.c +├── fdp_hw.h +├── fdp_g.c +├── fdp_aux.c +├── fdp_aux.h +├── fdcdp.c +├── fdcdp.h +├── fdcdp_param.c +├── fdcdp_intr.c +├── fdcdp_multi_display.c +├── fdcdp_multi_display.h + + +其中fdcdp.h 为用户开发者主要使用接口,提供了以下功能: +1. DC,DP 控制器控制器初始化接口 +2. DC,DP 控制器相关状态位的回调函数注册 +3. DC,DP 控制器中断处理函数 +4. DP热插拔检测处理函数 + + +## 数据结构 +```c +typedef struct +{ + /* fdc instace object */ + FDcCtrl dc_instance_p[FDCDP_INSTANCE_NUM]; + /* fdp instace object */ + FDpCtrl dp_instance_p[FDCDP_INSTANCE_NUM]; + /* user config */ + /* resolution */ + /* color depth */ + FDcDpDisplaySetting display_setting[FDCDP_DISPLAY_ID_MAX_NUM]; + /* gamma parameter */ + /* .... */ + /* uintptr fb_p[FDCDP_INSTANCE_NUM];*/ + u32 is_ready; /* Device is ininitialized and ready*/ + FMediaIntrConfig intr_event[FDCDP_INTR_MAX_NUM]; + + void *args; + u32 connect_flg[FDCDP_INSTANCE_NUM]; + u32 connect_changed_flg[FDCDP_INSTANCE_NUM]; +} FDcDp; +其中FdcPrivateParams结构体为dc模块相关变量,包含有时序,frambuffer,pannel,gamma,dither,cursor等等;FdpPrivateParams结构体为dp模块相关变量,包括有时序,传输参数,phy等等。 + +```c +dc 相关结构体定义 +typedef struct +{ + FDcDtdTable dtd_table; + FDcDisplayVHTimmingConfig timming_config; + FDcDisplayFramebuffer framebuffer; + FDcDisplayPanel panel; + FDcDisplayGamma gamma; + FDcDisplayDither dither; + FDcDisplayDpMode dp_mode; + FDcDisplayVideoMode video_mode; + FDcDisplayCursor cursor; +} FDcCurrentConfig; + +typedef struct +{ + u32 instance_id; /* dc id */ + uintptr dcch_baseaddr; /* DC channel register address*/ + uintptr dcctrl_baseaddr; /* DC control register address */ + u32 irq_num; /* Device intrrupt id */ + +} FDcConfig; + +typedef struct +{ + FDcCurrentConfig fdc_currentconfig; + FDcConfig config; + u32 multimode; /* The display mode of the device , including clone, horizontal and vertical display*/ + +} FDcCtrl; + +dp 相关结构体 + +typedef struct +{ + /* 设置参数 */ + FDpSyncParameter sync_parameter[DP_GOP_MAX_MODENUM]; + + FDpTransmissionConfig transmission_config; + + /* 当前状态 */ + FDpStatus status; + + u8 down_spread_enable; +#define dtd_list_max 4 + /* edid 缓冲数据 */ + FDpDtdTable dtd_table[dtd_list_max]; /* the max dtd num is 4 */ + +} FDpCurrentConfig; + +typedef struct +{ + u32 instance_id; + uintptr dp_channe_base_addr; + uintptr dp_phy_base_addr; + u32 irq_num; +} FDpConfig; + +typedef struct +{ + FDpCurrentConfig fdp_current_config; + FDpConfig config; +} FDpCtrl; + +中断 相关结构体 + +typedef enum +{ + FDCDP_HPD_IRQ_CONNECTED = 0, /* hpd 中断 */ + FDCDP_HPD_IRQ_DISCONNECTED, + FDCDP_AUX_REPLY_TIMEOUT, + FDCDP_AUX_REPLY_ERROR, + + FDCDP_INTR_MAX_NUM +} FDcDpIntrEventType; + +typedef void (*FDcDpIntrHandler )(void *param, u32 index); + +typedef struct +{ + FMediaIntrConfigtype; /* data */ + FDcDpIntrHandler handler; + void *param; +} FMediaIntrConfig; +``` + +## 错误码定义 +`` +FMEDIA_DEFAULT_PARAM_ERR /*获取默认参数失败 */ +FMEDIA_ERR_PIXEL /* 时钟设置错误 */ +FMEDIA_ERR_EDID /* EDID参数获取错误*/ +FMEDIA_AUX_CONNECT_FAILED /* AUX连接失败 */ +FMEDIA_TRAIN_TIME_ERR /* dp train次数超过5次还未能连接 */ +FMEDIA_REACH_MAX_VOLTAGE /*已经达到最大电压设置 */ + +`` +## 关键配置参数介绍 + +当您在使用显示驱动时,有必要将显示系统中的关键参数为您介绍: + +- resolution 分辨率 + +显示器能够呈现的最基本的单元是像素,显示器的显示区域正是被像素点所填充,显示器的分辨率就代表了显示器所能呈现的最大像素点,通常使用较多的是1024*768,1920*1080几种,在本驱动中,已将板卡支持分辨率统一至dpSyncTable,dcSyncTable中 + +- color depth 色深 + +色彩深度是用「n位元颜色」(n-bit colour)来作为单位的。若色彩深度是n位元,即有2的n次方种颜色选择,而储存每像素所用的位数目就是n,通常您见到最多的一般是16bit或32bit + +- fresh rate 刷新率 + +显示器每秒刷新画面的次数;单位是Hz;例如60Hz,120Hz + +- pixel clock 像素时钟 + +像素时钟 = 实际的水平像素*垂直像素*刷新率(像素数包括消隐数据) + +比如 {800 , 525 , 1 , 1 , 96 , 2 , 640 , 480 , 144 , 35 , 0 , 0 } 640*480@60Hz + +像素时钟 = 800*525*60 = 25.2 Mhz Vesa标准采用25.175 + +## 应用例程 +`` +- baremetal/example/peripheral/media/media_test +- baremetal/example/peripheral/media/lvgl + + 其中第一个例程只是点亮屏幕;第二个例程可与lvgl库进行连接,测试 + +## API 介绍 + +### 1. FDcConfig && FDpConfig + +``` +FDcConfig *FDcLookupConfig(u32 instance_id) +FDpConfig *FDpLookupConfig(u32 instance_id) +``` +#### 介绍 + +- 获取当前FDC驱动默认配置 + +- 获取当前FDP驱动默认配置 +#### 参数 +- u32 instance_id :当前media驱动中对应的ID + +#### 返回 +FDcConfig * :dc静态默认配置 +FDpConfig * :dp静态默认配置 + + +### 2. FDcDpSetBasicParam + +``` +FError FDcDpSetBasicParam(FDcDp *instance_p, u32 channel_num, u32 mode_id); +``` +#### 介绍 +- 根据传入配置,初始化MEDIA驱动实例,设置基本参数 + +#### 参数 +- FDcDp *instance_p FDcDp 控制器实例的指针 +- u32 channel_num DP通道号 +- u32 mode_id sync时序模式 + +#### 返回 +- FError :FMEDIA_DP_SUCCESS 为初始成功 + +### 3. FDcDpInitial + +``` +FError FDcDpInitial(FDcDp *instance_p, u32 channel_num, u32 mode_id, u32 multi_mode); +``` +#### 介绍 +- 初始化DC,DP,设置参数,包括dc,dp的初始化和连接 + +#### 参数 +- FDcDp *instance_p FDcDp 控制器实例的指针 +- u32 channel_num DP通道号 +- u32 mode_id sync时序模式 +- u32 multi_mode 单屏/多屏 + +#### 返回 +- FError :FMEDIA_DP_SUCCESS 为初始成功 + + +### 4. FDcDpRegisterHandler + +``` +void FDcDpRegisterHandler(FDcDp *instance_p, FMediaIntrConfig *intr_event_p) + +``` +#### 介绍 + +- 中断注册函数 + +#### 参数 +- FDcDp *instance_p FDcDp 控制器实例的指针 +- FMediaIntrConfig event_p 中断事件参数 + +### 5. FDcDpInterruptHandler + +``` +void FDcDpInterruptHandler(s32 vector, void *args); +``` + +#### 介绍 +-中断handle处理函数 + +#### 参数 +``` +s32 vector 中断返回值 +void *irq_args 回调结构体指针 +``` +#### 返回 +- NULL + +### 6. FDcDpIrqEnable + +``` +void FDcDpIrqEnable(FDcDp *instance_p, FMediaIntrConfigintr_event_p); +``` + +#### 介绍 +-中断使能函数 + +#### 参数 +``` +FDcDp *instance_p dcdp驱动实例 +FMediaIntrConfig intr_event_p 中断类型 +``` +#### 返回 +- NULL + +### 7. FDcDpMultiDisplayFrameBufferSet + +``` +FError FDcDpMultiDisplayFrameBufferSet(FDcDp *instance_p, u32 channel_num, u32 multi_mode); +``` + +#### 介绍 +-设置多屏模式下framebuffer参数 + +#### 参数 +``` +FDcDp *instance_p dcdp驱动实例 +u32 channel_num 通道号 +u32 multi_mode 单屏/多屏 +``` +#### 返回 +- FMEDIA_DP_SUCCESS + +### 8. FDcDpGetFramebuffer + +``` +FDcDpFrameBuffer *FDcDpGetFramebuffer(FDcDp *instance_p); +``` + +#### 介绍 +-提供framebuffer信息对外接口 + +#### 参数 +``` +FDcDp *instance_p dcdp驱动实例 +``` +#### 返回 +- &framebuffer_config +frambuffer信息 diff --git a/bsp/phytium/libraries/standalone/doc/reference/driver/fpwm.md b/bsp/phytium/libraries/standalone/doc/reference/driver/fpwm.md index c39a9c29a4..90bced080e 100644 --- a/bsp/phytium/libraries/standalone/doc/reference/driver/fpwm.md +++ b/bsp/phytium/libraries/standalone/doc/reference/driver/fpwm.md @@ -150,7 +150,7 @@ typedef enum - 获取Fata控制器默认配置 ```c -const FPwmConfig *FPwmLookupConfig(FPwmInstance instance_id); +const FPwmConfig *FPwmLookupConfig(u32 instance_id); ``` Note: @@ -159,7 +159,7 @@ Note: Input: -- {FPwmInstance} instance_id,pwm控制器id号 +- {u32} instance_id,pwm控制器id号 Return: diff --git a/bsp/phytium/libraries/standalone/doc/reference/driver/fscmi_mhu.md b/bsp/phytium/libraries/standalone/doc/reference/driver/fscmi_mhu.md new file mode 100644 index 0000000000..f29254fadc --- /dev/null +++ b/bsp/phytium/libraries/standalone/doc/reference/driver/fscmi_mhu.md @@ -0,0 +1,282 @@ +# SCMI_MHU 驱动程序 + +## 1. 概述 + +- SCMI_MHU(System Control and Management Interface)(Message Handling Unit)SCMI是用于系统管理的一组独立于操作系统的软件接口,MHU模块是SCP(System Control Processor)子系统的一个模块因为存在安全访问与非安全访问的区分所以采用APB4接口与SCP子系统和CPU核相连。 + +- AP与SCP之间的通信通过MHU与Shared memory实现。 + +- MHU模块主要实现CPU核与MCU通信通道的定义,分为物理通道和虚拟通道以及二者消息传递的控制功能,可实现双向通信。 + +``` + ______________________ ___________________________ __________________________ +|Application processor | |Message Handling Unit(MHU) | |System Control Processor | +| (AP) | <---> | Shared Memory | <---> | (SCP) | + —————————————————————— ——————————————————————————— —————————————————————————— +``` + +## 2. 功能 + +SCMI_MHU 驱动程序主要完成SCMI协议和MHU模块的初始化、MHU模块的收发置位、协议的组包和内存读写解析函数,该驱动程序具备以下功能: + +- 模块初始化 +- 模块的设置 +- 协议的组包 +- 共享内存的解析 + +相关源文件为: + +``` +fscmi_mhu + ├── fmhu_g.c + ├── fnhu_hw.h + ├── fmhu_intr.c(暂未实现) + ├── fmhu.c + ├── fmhu.h + ├── fscmi_base.c + ├── fscmi_base.h + ├── fscmi_perf.c + ├── fscmi_perf.h + ├── fscmi_sensors.c + ├── fscmi_sensors.h + ├── fscmi.c + └── fscmi.h +``` + +## 3. 配置方法 + +以下部分将指导您完成 SCMI_MHU 驱动的软件配置: + +- 配置驱动程序,新建应用工程,make menuconfig使能SCMI_MHU驱动模块 +- 设置配置参数,使用虚拟通道1,poll模式。(后续增加中断模式) +- 获取默认配置,设置使用MHU和shared memory地址 +- 调用API函数,获取或者设置SCP参数 + +## 4. 应用示例 + + +### [scmi_mhu](../../../baremetal/example/system/scmi_mhu/README.md) + + +## 5. API参考 + + +### 5.1. 用户数据结构 + +- drivers/scmi/fscmi_mhu/fscmi.h + +- scmi_mhu实例配置 + +```c +typedef struct +{ + u32 is_ready; /* Device is ininitialized and ready*/ + struct FScmiConfig config; + struct FScmiRevisionInfo revision; + struct FScmiSensorsInfo sensors; + struct FScmiPerfInfo perf; + struct FScmiTransferInfo info[FSCMI_SUPPORT_PROTOCOL_NUM]; + u8 protocols_imp[FSCMI_MAX_PROTOCOLS_IMP];/* List of protocols implemented, currently maximum of FSCMI_MAX_PROTOCOLS_IMP elements allocated by the base protocol */ + FScmiMhu scmi_mhu; +} FScmi; +``` + +```c +struct FScmiConfig +{ + uintptr share_mem; /* Chan transport protocol shared memory */ + u32 mbox_type; /* select mbox driver */ +}; +``` + +- 协议消息结构类型 + +```c +struct FScmiMsgHdr +{ + u8 id; /* message id */ + u8 protocol_id; /* protocol id */ + u16 seq; /* message token */ + u32 status; /* protocal status */ +}; + +struct FScmiMsg +{ + u8 buf[FSCMI_MSG_SIZE]; /* buffer in normal memory */ + fsize_t len; /* buffer length */ +}; + +struct FScmiTransferInfo +{ + struct FScmiMsgHdr hdr ; /* Message(Tx/Rx) header */ + struct FScmiMsg tx ; + struct FScmiMsg rx ; + boolean poll_completion; +}; +``` + +- 传感器信息结构 + +```c +struct FScmiSensorsInfo { + u32 version; + u16 major_ver; + u16 minor_ver; + u32 num_sensors; + u32 max_requests; + u64 reg_addr; + u32 reg_size; + struct FScmiSensorInfo sensor_info[FSCMI_MAX_NUM_SENSOR];/* TS0 TS1 */ +}; +``` + +```c +struct FScmiSensorInfo { + u32 id; + u8 type; + char name[FSCMI_MAX_STR_SIZE]; +}; +``` + +- Performance domain protocol + +```c +struct FScmiOpp { + u32 perf; + u32 power; + u32 trans_latency_us; +}; + +struct FPerfDomInfo { + boolean set_limits; + boolean set_perf; + boolean perf_limit_notify; + boolean perf_level_notify; + u32 opp_count; + u32 sustained_freq_khz; + u32 sustained_perf_level; + u32 mult_factor; + char name[FSCMI_MAX_STR_SIZE]; + struct FScmiOpp opp[FSCMI_MAX_OPPS]; +}; + +struct FScmiPerfInfo { + u32 version; + u16 major_ver; + u16 minor_ver; + u32 num_domains; + boolean power_scale_mw; + u64 stats_addr; + u32 stats_size; + struct FPerfDomInfo dom_info[FSCMI_MAX_PERF_DOMAINS]; +}; +``` + +- 基础协议信息结构 + +```c +struct FScmiRevisionInfo /* base protocol */ +{ + u32 version; + u16 major_ver; + u16 minor_ver; + u8 num_protocols; + u8 num_agents; + u32 impl_ver; + char vendor_id[FSCMI_MAX_STR_SIZE]; + char sub_vendor_id[FSCMI_MAX_STR_SIZE]; +}; +``` + +### 5.2 错误码定义 + +- FSCMI_ERROR_TYPE : 使用错误的驱动类型 +- FSCMI_ERROR_RANGE : 超出设定值范围 +- FSCMI_ERROR_NOT_FOUND : 没有找的对应的协议类型 +- FSCMI_ERROR_NULL_POINTER : 空指针 +- FSCMI_ERROR_WAIT_MBOX_TIMEOUT : mailbox超时 +- FSCMI_ERROR_WAIT_MEM_TIMEOUT : 共享内存访问超时 +- FSCMI_ERROR_FETCH_RESPONSE : 回复错误 +- FSCMI_ERROR_REQUEST : 错误请求 +- FSCMI_ERROR_VERSION : 版本号错误 +- FSCMI_ERROR_INIT : 初始化错误 + +### 5.3. 用户API接口 + +- 配置scmi初始化参数 + +```c +FError FScmiCfgInitialize(FScmi *instance_p, const struct FScmiConfig *config); +``` + +- 获取传感器的信息 + +```c +FError FScmiSensorGetInfo(FScmi *instance_p); +``` + +- scmi协议消息的初始化 + +```c +FError FScmiMessageInit(FScmi *instance_p, u8 msg_id, u8 pro_id, u32 tx_size, u32 rx_size, u8 *tx_buffer); +``` + +- scmi协议发送准备,将初始化完成消息协议写入共享内存 + +```c +FError FScmiProtocolTxPrepare(FScmi *instance_p, u8 pro_id); +``` + +- 等待共享内存的协议完成 + +```c +FError FScmiProtocolPollDone(FScmi *instance_p, u8 pro_id); +``` + +- 获取共享内存SCP的回复数据 + +```c +FError FScmiFetchResponse(FScmi *instance_p, u8 pro_id); +``` + +- 获取对应协议的消息表指针 + +```c +struct FScmiTransferInfo *FScmiGetInfo(FScmi *instance_p, u8 pro_id); +``` + +- 进行传输 + +```c +FError FScmiDoTransport(FScmi *instance_p, struct FScmiTransferInfo *info, u32 protocol_index); +``` + +- 传感器初始化 + +```c +FError FScmiSensorInit(FScmi *instance_p); +``` + +- 传感器温度的获取,需要初始化成功 + +```c +FError FScmiSensorGetTemp(FScmi *instance_p, u32 sensor_id,s64 *temp); +``` + +- 性能域的初始化 + +```c +FError FScmiPerfInit(FScmi *instance_p); +``` + +- 设置域性能 + +```c +FError FScmiDvfsFreqSet(FScmi *instance_p, u32 domain, u64 freq, boolean poll); +``` + +- 获取域性能 + +```c +FError FScmiDvfsFreqGet(FScmi *instance_p, u32 domain, u64 *freq, boolean poll); +``` diff --git a/bsp/phytium/libraries/standalone/doc/reference/driver/fsdio.md b/bsp/phytium/libraries/standalone/doc/reference/driver/fsdio.md index ec8029e973..606c7154c7 100644 --- a/bsp/phytium/libraries/standalone/doc/reference/driver/fsdio.md +++ b/bsp/phytium/libraries/standalone/doc/reference/driver/fsdio.md @@ -55,6 +55,8 @@ typedef struct _FSdio FSdioIDmaDescList desc_list; /* DMA descriptor list, valid in DMA trans mode */ FSdioEvtHandler evt_handlers[FSDIO_NUM_OF_EVT]; /* call-backs for interrupt event */ void *evt_args[FSDIO_NUM_OF_EVT]; /* arguments for event call-backs */ + FSdioRelaxHandler relax_handler; + u32 prev_cmd; /* record previous command code */ } FSdio; /* SDIO intance */ ``` @@ -71,6 +73,8 @@ typedef struct FSdioTransMode trans_mode; /* Trans mode, PIO/DMA */ FSdioSpeedType speed; /* Trans speed type */ FSdioVoltageType voltage; /* Card voltage type */ + boolean non_removable; /* No removeable media, e.g eMMC */ + boolean filp_resp_byte_order; /* Some SD protocol implmentation may not do byte-order filp */ } FSdioConfig; /* SDIO intance configuration */ ``` #### FSdioCmdData @@ -237,6 +241,26 @@ Return: - {None} +#### FSdioGetClkFreq + +```c +u32 FSdioGetClkFreq(FSdio *const instance_p) +``` + +Note: + +- Get the Card clock freqency + +Input: + +- {FSdio} *instance_p, SDIO controller instance + +Return: + +- {u32} real clock in Hz + + + #### FSdioDMATransfer ```c @@ -259,7 +283,7 @@ Return: #### FSdioPollWaitDMAEnd ```c -FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax) +FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) ``` Note: @@ -270,7 +294,6 @@ Input: - {FSdio} *instance_p, SDIO controller instance - {FSdioCmdData} *cmd_data_p, contents of transfer command and data -- {FSdioRelaxHandler} relax, handler of relax when wait busy Return: @@ -381,7 +404,7 @@ Return: #### FSdioPollWaitPIOEnd ```c -FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax); +FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); ``` Note: @@ -392,7 +415,6 @@ Input: - {FSdio} *instance_p, SDIO controller instance - {FSdioCmdData} *cmd_data_p, contents of transfer command and data -- {FSdioRelaxHandler} relax, handler of relax when wait busy Return: diff --git a/bsp/phytium/libraries/standalone/doc/reference/driver/fsdmmc.md b/bsp/phytium/libraries/standalone/doc/reference/driver/fsdmmc.md index e4805188bf..5994269b45 100644 --- a/bsp/phytium/libraries/standalone/doc/reference/driver/fsdmmc.md +++ b/bsp/phytium/libraries/standalone/doc/reference/driver/fsdmmc.md @@ -58,6 +58,7 @@ typedef struct FSdmmcConfig config; /* Current active configs */ u32 is_ready; /* Device is initialized and ready */ FSdmmcEventHandler evt_handler[FSDMMC_EVT_NUM]; + void *evt_args[FSDMMC_EVT_NUM]; } FSdmmc; /* Device instance */ ``` @@ -364,7 +365,7 @@ Return: - 注册中断事件响应函数 ```c -void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler); +void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler, void *args); ``` Note: @@ -380,4 +381,4 @@ Input: Return: -- 无 \ No newline at end of file +- 无 diff --git a/bsp/phytium/libraries/standalone/doc/reference/driver/fxmac.md b/bsp/phytium/libraries/standalone/doc/reference/driver/fxmac.md index d3d6fe56fe..4ce27297f6 100644 --- a/bsp/phytium/libraries/standalone/doc/reference/driver/fxmac.md +++ b/bsp/phytium/libraries/standalone/doc/reference/driver/fxmac.md @@ -102,12 +102,12 @@ XMAC 驱动程序的源文件包括, u32 auto_neg; /* Enable auto-negotiation - when set active high, autonegotiation operation is enabled. */ u32 pclk_hz; u32 max_queue_num; /* Number of Xmac Controller Queues */ - u32 tx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ - u32 rx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 tx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 rx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ u32 hotplug_irq_num; u32 dma_brust_length; /* burst length */ u32 network_default_config; /* mac 控制器默认配置 */ - u32 queue_irq_num[FT_XMAC_QUEUE_MAX_NUM]; /* mac0 8个 ,其他的 4个 */ + u32 queue_irq_num[FXMAC_QUEUE_MAX_NUM]; /* mac0 8个 ,其他的 4个 */ } FXmacConfig; ``` diff --git a/bsp/phytium/libraries/standalone/doc/reference/sdk/flwip_port.md b/bsp/phytium/libraries/standalone/doc/reference/sdk/flwip_port.md new file mode 100644 index 0000000000..0c109e62c1 --- /dev/null +++ b/bsp/phytium/libraries/standalone/doc/reference/sdk/flwip_port.md @@ -0,0 +1,182 @@ + +# Lwip Port + +## 1. 概述 + +Lwip Port为开发者提供了一系列接口,驱动开发者在完成GMAC/XMAC 驱动之后,只需根据lwip要求的接口,将驱动内容填入,即可完成lwip port适配层功能。lwip port 会在初始化阶段,初始化协议栈,并且会根据用户传入的配置参数,并初始化netif参数。 + +## 2. 功能 + +1. 为开发者提供lwip功能与mac控制驱动耦合的相关接口 +2. 统一后续mac控制器接入lwip 协议栈的方式 +3. 简化mac 控制器适配lwip 的难度 +4. 统一不同mac 控制器下应用程序 +5. 提供上层用户配置mac 控制器的统一接口 +6. 管理mac 控制器的状态(phy link status) +7. 管理lwip 中link up/down 状态 +8. 提供多网卡检索功能 + +相关源文件为: +``` +lwip_port + ├── lwip_port.c + └── lwip_port.h +``` + + +## 3. 配置方法 + +默认配置已经保存在config中,用户可根据实际需要自行扩展,该部分操作参考readme即可 + +## 4. 应用示例 + +### [lwip port](../../../baremetal/example/network/lwip_startup/) + +## 5. API参考 + +### 5.1. 用户数据结构 + +- lwip_port.h + +```c +typedef struct +{ + u32 magic_code; /* LWIP_PORT_CONFIG_MAGIC_CODE */ + char name[2]; /* Used to name netif */ + u32 driver_type; /* driver type */ + u32 mac_instance; /* mac controler id */ + u32 mii_interface; /* LWIP_PORT_INTERFACE_XXX */ + u32 autonegotiation; /* 1 is autonegotiation ,0 is manually set */ + u32 phy_speed; /* LWIP_PORT_SPEED_XXX */ + u32 phy_duplex; /* 1 is LWIP_PORT_FULL_DUPLEX,0 is LWIP_PORT_HALF_DUPLE*/ +} UserConfig; /*用户初始化配置数据 */ + +typedef struct +{ + void (*eth_input)(struct netif *netif); + enum lwip_port_link_status (*eth_detect)(struct netif *netif); + void (*eth_deinit)(struct netif *netif); + void (*eth_start)(struct netif *netif); +} LwipPortOps; /* lwip port 网卡注册函数*/ + +struct LwipPort { + void *state; /* mac controler */ + LwipPortOps ops; +}; /*lwip port控制数据 */ +``` + +### 5.2 错误码定义 +无 +### 5.3. 用户API接口 + +#### LwipPortAdd +- 作为 lwip 的netif_add 的一个封装,开发者可以通过此接口对不同mac 控制器进行初始化 + +```c +struct netif * LwipPortAdd(struct netif *netif, +ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, +unsigned char *mac_ethernet_address, +UserConfig *user_config, u32 dhcp_en); +``` + +Note: + +- begin_addr end_addr 指向为内存池指定的缓冲区的起止地址 + +Input: + +- {struct netif } *netif, 需要初始化的网卡对象 +- {ip_addr_t} *ipaddr, 分配给网卡的IP初始地址 +- {ip_addr_t} *netmask, 分配给掩码的IP初始地址 +- {ip_addr_t} *gw, 分配给网关的IP初始地址 +- {unsigned char } *mac_ethernet_address, 分配给网卡的mac初始地址 +- {UserConfig} *user_config, 网卡初始化所需要的用户配置数据 +- {u32} dhcp_en, 网卡是否使用dhcp服务控制数据 +Return: + +- {struct netif *} 返回初始化成功的netif网卡对象,返回NULL表示初始化失败 + +#### LwipPortInput + +- lwip协议栈获取驱动数据包的接口,客户可以使用此接口在裸跑中运行lwip 协议栈 + +```c +void LwipPortInput(struct netif *netif) +``` + +Note: + +- 需要初始化后才能调用,调用此函数后,lwip会获取网卡收到的数据包并进行处理 + +Input: + +- {struct netif } *netif 已经实例化的网卡netif + +Return: + +- 无 + +#### LwipPortStop + +- 使用此接口可以达到两个目标: +1. 关闭当前mac 控制器工作状态 +2. 将netif 移除lwip 协议栈 + + +```c +void LwipPortStop(struct netif *netif); +``` + +Note: + +- 需要初始化后才能调用,调用该函数后,网卡将停止功能,若想继续工作需要重新进行网卡初始化 + +Input: + +- {struct netif } *netif 已经实例化的网卡netif + +Return: + +- 无 +#### LwipPortGetByName + +- 通过netif名字找到netif对象 + +```c +struct netif* LwipPortGetByName(const char *name); +``` + +Note: + +- 需要初始化后才能调用,调用该函数将在已经初始化的netif链表中寻找name字段相对应的netif,并返回该netif + +Input: + +- {const char} *name 网卡名字 + +Return: + +- {struct netif*} 寻找到的netif对象,如果未找到返回NULL + +#### LwipPortDhcpSet + +- 网卡dhcp控制 + +```c +void LwipPortDhcpSet(struct netif *netif, boolean is_enabled); +``` + +Note: + +- 需要初始化后才能调用,调用该函数可以打开或关闭网卡的dhcp服务 + +Input: + +- {struct netif} *netif 网卡对象 +- {boolean} is_enabled DHCP使能控制参数 + + +Return: + +- 无 + diff --git a/bsp/phytium/libraries/standalone/doc/reference/usr/usage.md b/bsp/phytium/libraries/standalone/doc/reference/usr/usage.md index 2e03a76df1..d461ec0161 100644 --- a/bsp/phytium/libraries/standalone/doc/reference/usr/usage.md +++ b/bsp/phytium/libraries/standalone/doc/reference/usr/usage.md @@ -170,6 +170,134 @@ tftp> q - 将镜像文件放置在上图所示的`%PHYTIUM_IDE_PATH%\tftp`目录下,开发板即可通过`tftpboot`加载镜像 > 在`template_mingw64`工程中,通过定义`USR_BOOT_DIR`可以将编译的镜像自动拷贝带tftp目录下 --> + + +### 1.2.3 设置板载FLASH自动启动,避免人工干预 + +- 此项设置是把bin镜像保存到和UBOOT相同的NOR FLASH芯片里。此芯片一般8MB。目前uboot里的flash读写命令,最大支持16MB +- uboot固件一般4MB左右。以下命令例子,把前6MB给uboot,从6MB到7MB的空间给bin镜像使用,操作命令如下, + +- 通过串口或者网络下载到内存 +``` +loadx 0x90100000 +tftpboot 0x90100000 baremetal.elf +``` + +- 将下载的镜像写入 QSPI NOR-Flash,位置为 0x600000,镜像大小为 0x100000 +> 如果下载的 bin/elf 镜像大小超过 0x100000 字节,需要随镜像大小进行调整 +``` +flashe 0x600000 0x100000 +flashw 0x90100000 0x600000 0x100000 +cmp.b 0x600000 0x90100000 0x100000 +cp.b 0x600000 0x90100000 0x100000 +``` + +- 然后就可以下电、上电启动,自动从 QSPI NOR-Flash 引导系统 +> 使用 saveenv 前,需要找 FAE 确认 u-boot 版本是否支持 +``` +csetenv bootcmd "cp.b 0x600000 0x90100000 0xa00000; bootvx32 0x90100000" +saveenv +``` + +- 如果用baremetal.bin文件,则把0x90100000改成0x80100000即可 + +### 1.2.4 将镜像放置在 SD 卡文件系统中,进行启动 + +- 以 Windows 10为例, 首先利用读卡器或者 SD 卡套将 SD 插入 Windows10 电脑接口,找到 SD 卡对应的磁盘 + +![](../../fig/disk_manager.png) + +- 在 SD 卡磁盘上创建一个分区,格式为 FAT,由于 FAT 格式限制,分区不能超过太大,我们这里创建 256 MB 分区就可以了 + +![](../../fig/sd_segement.png) + +- 将编译生成的 bin 文件或者 elf 文件放置在刚刚创建的 FAT 格式分区中 + +![](../../fig/sd_image.png) + +- 将 SD 卡从 Windows10 电脑中正常弹出,将 SD 卡插入开发板卡槽 + +![](../../fig/sd_insert.png) + +- 启动开发板,进入 u-boot 控制台,输入下列命令找到 bin/elf 镜像文件 +> 以 E2000-Demo 板为例,SD 卡槽连接的是 SD-1 控制器, + +``` +mmc dev 1 +mmc info +fatls mmc 1:1 +``` + +![](../../fig/sd_partinfo.png) + +- 输入下列命令加载 elf 镜像,开始启动 + +``` +fatload mmc 1:1 0xa0100000 baremetal.elf +bootelf -p 0xa0100000 +``` + +- 使用 bin 镜像启动前,需要确保刷新过 cache +``` +fatload mmc 1:1 0x80100000 baremetal.bin +dcache flush +go 0x80100000 +``` + +- 输入下列命令,可以下电、上电启动,自动从 SD 卡介质中引导系统 +> 使用 saveenv 前,需要找 FAE 确认 u-boot 版本是否支持 +``` +setenv bootcmd "mmc dev 1; fatload mmc 1:1 0x90100000 baremetal.elf; bootelf -p 0x90100000" +saveenv +``` + + +### 1.2.5 将镜像放置在 U盘文件系统中,进行启动 + +- 以 Windows 10为例, 首先将 U 盘插入 Windows10 电脑接口,找到 SD 卡对应的磁盘 +- 在 U 盘上创建一个分区,格式为 FAT,由于 FAT 格式限制,分区不能超过太大,我们这里创建 128 MB 分区就可以了 + +![](../../fig/usb_disk.png) + +- 将编译生成的 bin 文件或者 elf 文件放置在刚刚创建的 FAT 格式分区中 + +- 将 U 盘从 Windows10 电脑中正常弹出,将 U 盘插入开发板USB插槽 + +![](../../fig/usb_insert.png) + +- 启动 USB 控制器,找到 U 盘中的 + +``` +usb start +usb storage +fatls usb 0 +``` + +![](../../fig/usb_image.png) + + +- 输入下列命令加载 elf 镜像,开始启动 + +``` +fatload usb 0 0xa0100000 baremetal.elf +bootelf -p 0xa0100000 +``` + +- 使用 bin 镜像启动前,需要确保刷新过 cache + +``` +ffatload usb 0 0x80100000 baremetal.bin +dcache flush +go 0x80100000 +``` + +- 输入下列命令,可以下电、上电启动,自动从 U盘引导系统 +> 使用 saveenv 前,需要找 FAE 确认 u-boot 版本是否支持 +``` +setenv bootcmd "usb start; fatload usb 0 0x90100000 baremetal.elf; bootelf -p 0x90100000" +saveenv +``` + ## 1.3 新建一个baremetal应用工程 如果您希望自己建立一个应用工程,可以参考下面的流程 ### 1.3.1 选择工程模板 diff --git a/bsp/phytium/libraries/standalone/drivers/Kconfig b/bsp/phytium/libraries/standalone/drivers/Kconfig index 27388c475c..d1b0530500 100644 --- a/bsp/phytium/libraries/standalone/drivers/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/Kconfig @@ -27,7 +27,7 @@ config USE_GIC default y help Include Generic Interrupt Controllor - + if USE_GIC source "$STANDALONE_DIR/drivers/gic/Kconfig" endif @@ -38,7 +38,7 @@ config USE_SERIAL default n help Include serial modules and enable serial - + if USE_SERIAL source "$STANDALONE_DIR/drivers/serial/Kconfig" endif @@ -150,18 +150,18 @@ config USE_DMA prompt "Use DMA" default n help - Include DMA + Include DMA if USE_DMA source "$STANDALONE_DIR/drivers/dma/Kconfig" endif - + config USE_NAND bool prompt "Use NAND" help Include NAND - + if USE_NAND source "$STANDALONE_DIR/drivers/nand/Kconfig" endif @@ -187,7 +187,7 @@ config USE_SATA if USE_SATA source "$STANDALONE_DIR/drivers/sata/Kconfig" endif - + config USE_USB bool prompt "Use USB" @@ -197,8 +197,8 @@ config USE_USB if USE_USB source "$STANDALONE_DIR/drivers/usb/Kconfig" - endif - + endif + config USE_ADC bool prompt "Use ADC" @@ -209,7 +209,7 @@ config USE_ADC if USE_ADC source "$STANDALONE_DIR/drivers/adc/Kconfig" endif - + config USE_PWM bool prompt "Use PWM" @@ -233,5 +233,27 @@ config USE_IPC endif +config USE_MEDIA + bool + prompt "USE MEDIA" + default n + help + Include media drivers + + if USE_MEDIA + source "$STANDALONE_DIR/drivers/media/Kconfig" + endif + +config USE_SCMI_MHU + bool + prompt "USE SCMI_MHU" + default n + help + Include scmi_mhu drivers + + if USE_SCMI_MHU + source "$STANDALONE_DIR/drivers/scmi/Kconfig" + endif + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/adc/Kconfig b/bsp/phytium/libraries/standalone/drivers/adc/Kconfig index 15ffeaa8fe..58f7dd8a6f 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/adc/Kconfig @@ -4,7 +4,7 @@ menu "ADC Configuration" bool prompt "Use FADC" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.c b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.c index 83247b60e6..2cd42b1538 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.c +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.c @@ -14,12 +14,14 @@ * FilePath: fadc.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:45 - * Description:  This files is for + * Description: This file is for the minimum required function implementations for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/15 init commit */ + #include #include "fgeneric_timer.h" #include "fkernel.h" @@ -178,7 +180,7 @@ FError FAdcConvertSet(FAdcCtrl *pctrl, FAdcConvertConfig *convert_config) FASSERT(clk_div < FADC_MAX_CLOCK_PRESC); if (clk_div % 2 == 1) { - FADC_ERROR("clk_div is not even."); + FADC_ERROR("Clk_div is not even."); return FADC_ERR_INVAL_PARM; } reg_val &= (~FADC_CTRL_REG_CLK_DIV_MASK); @@ -236,24 +238,24 @@ FError FAdcInterruptEnable(FAdcCtrl *pctrl, FAdcChannel channel, FAdcIntrEventTy reg_val = FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET); switch (event_type) { - case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */ - reg_val &= ~(FADC_INTRMASK_REG_COVFIN_MASK(channel)); - break; + case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */ + reg_val &= ~(FADC_INTRMASK_REG_COVFIN_MASK(channel)); + break; - case FADC_INTR_EVENT_DLIMIT: - reg_val &= ~(FADC_INTRMASK_REG_DLIMIT_MASK(channel)); - break; + case FADC_INTR_EVENT_DLIMIT: + reg_val &= ~(FADC_INTRMASK_REG_DLIMIT_MASK(channel)); + break; - case FADC_INTR_EVENT_ULIMIT: - reg_val &= ~(FADC_INTRMASK_REG_ULIMIT_MASK(channel)); - break; + case FADC_INTR_EVENT_ULIMIT: + reg_val &= ~(FADC_INTRMASK_REG_ULIMIT_MASK(channel)); + break; - case FADC_INTR_EVENT_ERROR: - reg_val &= ~(FADC_INTRMASK_REG_ERR_MASK); - break; + case FADC_INTR_EVENT_ERROR: + reg_val &= ~(FADC_INTRMASK_REG_ERR_MASK); + break; - default: - break; + default: + break; } FADC_WRITE_REG32(base_addr, FADC_INTRMASK_REG_OFFSET, reg_val); @@ -281,24 +283,24 @@ FError FAdcInterruptDisable(FAdcCtrl *pctrl, FAdcChannel channel, FAdcIntrEventT reg_val = FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET); switch (event_type) { - case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */ - reg_val |= (FADC_INTRMASK_REG_COVFIN_MASK(channel)); - break; + case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */ + reg_val |= (FADC_INTRMASK_REG_COVFIN_MASK(channel)); + break; - case FADC_INTR_EVENT_DLIMIT: - reg_val |= (FADC_INTRMASK_REG_DLIMIT_MASK(channel)); - break; + case FADC_INTR_EVENT_DLIMIT: + reg_val |= (FADC_INTRMASK_REG_DLIMIT_MASK(channel)); + break; - case FADC_INTR_EVENT_ULIMIT: - reg_val |= (FADC_INTRMASK_REG_ULIMIT_MASK(channel)); - break; + case FADC_INTR_EVENT_ULIMIT: + reg_val |= (FADC_INTRMASK_REG_ULIMIT_MASK(channel)); + break; - case FADC_INTR_EVENT_ERROR: - reg_val |= (FADC_INTRMASK_REG_ERR_MASK); - break; + case FADC_INTR_EVENT_ERROR: + reg_val |= (FADC_INTRMASK_REG_ERR_MASK); + break; - default: - break; + default: + break; } FADC_WRITE_REG32(base_addr, FADC_INTRMASK_REG_OFFSET, reg_val); @@ -430,7 +432,7 @@ FError FAdcReadConvertResult(FAdcCtrl *pctrl, FAdcChannel channel, u16 *val) if (0 >= timeout) { - FADC_ERROR("timeout when read adc data, convert is not completed."); + FADC_ERROR("Timeout when reading adc-data, the conversion is not finished."); *val = 0; return FADC_ERR_TIMEOUT; } @@ -521,7 +523,7 @@ FError FAdcCfgInitialize(FAdcCtrl *pctrl, const FAdcConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == pctrl->is_ready) { - FADC_WARN("device is already initialized!!!"); + FADC_WARN("The device was already initialized!"); } /*Set default values and configuration data */ diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.h b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.h index a7c96131f9..118ba1294c 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.h +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc.h @@ -14,20 +14,16 @@ * FilePath: fadc.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:29:10 - * Description:  This files is for + * Description: This file is for detailed description of the device configuration and driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ -#ifndef FT_ADC_H -#define FT_ADC_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FADC_H +#define FADC_H #include "ftypes.h" #include "fdebug.h" @@ -36,6 +32,12 @@ extern "C" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + #define FADC_SUCCESS FT_SUCCESS #define FADC_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspAdc, 1) #define FADC_ERR_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspAdc, 2) @@ -125,7 +127,7 @@ typedef struct } FAdcCtrl; /* get default configuration of specific adc id */ -const FAdcConfig *FAdcLookupConfig(FAdcInstance instance_id); +const FAdcConfig *FAdcLookupConfig(u32 instance_id); /* DeInitialization function for the device instance */ void FAdcDeInitialize(FAdcCtrl *pctrl); diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_g.c b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_g.c index aae6f24981..925692589a 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_g.c +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_g.c @@ -14,32 +14,25 @@ * FilePath: fadc_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:45 - * Description:  This files is for + * Description: This file is for adc static configuration implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/16 init commit */ + #include "fparameters.h" #include "fadc.h" -/* default configs of wdt ctrl */ -const FAdcConfig FAdcConfigTbl[FADC_INSTANCE_NUM] = +/* default configs of adc ctrl */ +const FAdcConfig FAdcConfigTbl[FADC_NUM] = { { - .instance_id = FADC_INSTANCE_0, - .base_addr = FADC0_CONTROL_BASE, - .irq_num = FADC0_INTR_IRQ, + .instance_id = FADC0_ID, + .base_addr = FADC0_BASE_ADDR, + .irq_num = FADC0_IRQ_NUM, .irq_prority = 0, .instance_name = "ADC-0" - - }, - - { - .instance_id = FADC_INSTANCE_1, - .base_addr = FADC1_CONTROL_BASE, - .irq_num = FADC1_INTR_IRQ, - .irq_prority = 0, - .instance_name = "ADC-1" } }; \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.c b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.c index c1e5cc63f7..9695f562cd 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.c @@ -14,17 +14,24 @@ * FilePath: fadc_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * Description: This file is for adc register implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ #include "fparameters.h" #include "fadc_hw.h" #include "stdio.h" +#define FADC_DEBUG_TAG "FT_ADC_HW" +#define FADC_DEBUG(format, ...) FT_DEBUG_PRINT_D(FADC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FADC_INFO(format, ...) FT_DEBUG_PRINT_I(FADC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FADC_WARN(format, ...) FT_DEBUG_PRINT_W(FADC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FADC_ERROR(format, ...) FT_DEBUG_PRINT_E(FADC_DEBUG_TAG, format, ##__VA_ARGS__) + /** * @name: FAdcDump * @msg: debug register value for adc channel. @@ -34,15 +41,15 @@ */ void FAdcDump(uintptr base_addr, u8 channel) { - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_CTRL_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET)); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_INTER_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTER_REG_OFFSET)); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_STATE_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_STATE_REG_OFFSET)); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_INTRMASK_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET)); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_INTR_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTR_REG_OFFSET)); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_COV_RESULT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_COV_RESULT_REG_OFFSET(channel))); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_FINISH_CNT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_FINISH_CNT_REG_OFFSET(channel))); - printf("Off[0x%02x]: = 0x%08x\r\n", FADC_HIS_LIMIT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_HIS_LIMIT_REG_OFFSET(channel))); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_CTRL_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET)); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_INTER_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTER_REG_OFFSET)); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_STATE_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_STATE_REG_OFFSET)); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_INTRMASK_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET)); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_INTR_REG_OFFSET, FADC_READ_REG32(base_addr, FADC_INTR_REG_OFFSET)); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_COV_RESULT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_COV_RESULT_REG_OFFSET(channel))); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_FINISH_CNT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_FINISH_CNT_REG_OFFSET(channel))); + FADC_INFO("Off[0x%02x]: = 0x%08x", FADC_HIS_LIMIT_REG_OFFSET(channel), FADC_READ_REG32(base_addr, FADC_HIS_LIMIT_REG_OFFSET(channel))); - printf("\r\n"); + FADC_INFO(""); } diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.h b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.h index e9abff56b2..0796906dd9 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_hw.h @@ -14,24 +14,27 @@ * FilePath: fadc_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:45 - * Description:  This files is for + * Description: This file is for adc register definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ -#ifndef BSP_DRIVERS_ADC_HW_H -#define BSP_DRIVERS_ADC_HW_H + +#ifndef FADC_HW_H +#define FADC_HW_H + +#include "fkernel.h" +#include "ftypes.h" +#include "fio.h" +#include "fdebug.h" #ifdef __cplusplus extern "C" { #endif -#include "fkernel.h" -#include "ftypes.h" -#include "fio.h" - /* Generic ADC register definitions */ /* FADC register */ diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_intr.c b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_intr.c index 6a6ac7ba60..f161eb64c4 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_intr.c @@ -14,15 +14,16 @@ * FilePath: fadc_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:45 - * Description:  This files is for + * Description:  This file is for adc interrupt handler implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ + #include "fparameters.h" #include "fassert.h" -#include "finterrupt.h" #include "fadc.h" #include "fadc_hw.h" @@ -68,7 +69,6 @@ void FAdcIntrHandler(s32 vector, void *args) FAdcCtrl *pctrl = (FAdcCtrl *)args; u32 status = 0; u32 intrmask = 0; - u32 cfg = 0; u32 channel = 0; uintptr base_addr = pctrl->config.base_addr; diff --git a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_sinit.c b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_sinit.c index b6f415db2a..1335e3bd0c 100644 --- a/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/adc/fadc/fadc_sinit.c @@ -14,11 +14,12 @@ * FilePath: fadc_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * Description: This file is for adc static variables implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ @@ -29,7 +30,7 @@ #include "fadc.h" #include "fassert.h" -extern FAdcConfig FAdcConfigTbl[FADC_INSTANCE_NUM]; +extern FAdcConfig FAdcConfigTbl[FADC_NUM]; /************************** Constant Definitions *****************************/ @@ -44,17 +45,17 @@ extern FAdcConfig FAdcConfigTbl[FADC_INSTANCE_NUM]; /** * @name: FAdcLookupConfig * @msg: get default configuration of specific adc id. - * @param {FAdcInstance} instance_id, instance id of FADC controller + * @param {u32} instance_id, instance id of FADC controller * @return {FAdcConfig*} Default configuration parameters of FADC */ -const FAdcConfig *FAdcLookupConfig(FAdcInstance instance_id) +const FAdcConfig *FAdcLookupConfig(u32 instance_id) { const FAdcConfig *pconfig = NULL; - FASSERT(instance_id < FADC_INSTANCE_NUM); + FASSERT(instance_id < FADC_NUM); u32 index = 0; - for (index = 0; index < (u32)FADC_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FADC_NUM; index++) { if (FAdcConfigTbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/can/Kconfig b/bsp/phytium/libraries/standalone/drivers/can/Kconfig index c3e16b4834..33dfe2855f 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/can/Kconfig @@ -6,13 +6,13 @@ menu "CAN Configuration" default n if USE_FCAN config FCAN_USE_CANFD - depends on TARGET_E2000 + depends on TARGET_E2000 || TARGET_TARDIGRADE bool prompt "Use CanFD" default n help use canfd protocol endif - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.c b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.c index 9de3f128f4..83058453b1 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.c +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.c @@ -14,11 +14,14 @@ * FilePath: fcan.c * Date: 2021-04-29 10:21:53 * LastEditTime: 2022-02-18 08:29:20 - * Description:  This files is for + * Description:  This files is for the can functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release + * 1.1 wangxiaodong 2022/9/23 improve functions + * 1.2 zhangyan 2022/12/7 improve functions */ #include "string.h" @@ -113,7 +116,9 @@ static s32 FCanUpdateSamplePoint(const FCanBittimingConst *btc, } if (sample_point_error_ptr) + { *sample_point_error_ptr = best_sample_point_error; + } return best_sample_point; } @@ -162,40 +167,62 @@ static FError FCanCalcBittiming(FCanBaudrateConfig *bt_p, u32 target_baudrate, u } else { - if (target_baudrate > 1000000) + if (target_baudrate > 4000000) + { sample_point_nominal = 650; + } + else if (target_baudrate > 2000000) + { + sample_point_nominal = 680; + } + else if (target_baudrate > 1000000) + { + sample_point_nominal = 725; + } else if (target_baudrate > 800000) + { sample_point_nominal = 750; + } else if (target_baudrate > 500000) + { sample_point_nominal = 800; + } else + { sample_point_nominal = 875; + } } for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; - tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) + tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { tsegall = CAN_CALC_SYNC_SEG + tseg / 2; /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ - brp = FCAN_REF_CLOCK / (tsegall * target_baudrate) + tseg % 2; + brp = FCAN_CLK_FREQ_HZ / (tsegall * target_baudrate) + tseg % 2; /* choose brp step which is possible in system */ brp = (brp / btc->brp_inc) * btc->brp_inc; if ((brp < btc->brp_min) || (brp > btc->brp_max)) + { continue; + } - baudrate = FCAN_REF_CLOCK / (brp * tsegall); + baudrate = FCAN_CLK_FREQ_HZ / (brp * tsegall); baudrate_error = abs(target_baudrate - baudrate); /* tseg brp biterror */ if (baudrate_error > best_baudrate_error) + { continue; + } /* reset sample point error if we have a better baudrate */ if (baudrate_error < best_baudrate_error) + { best_sample_point_error = UINT_MAX; + } FCanUpdateSamplePoint(btc, sample_point_nominal, tseg / 2, &tseg1, &tseg2, &sample_point_error); @@ -216,7 +243,9 @@ static FError FCanCalcBittiming(FCanBaudrateConfig *bt_p, u32 target_baudrate, u FCAN_DEBUG("reg_val=%#x\n", reg_val); if (sample_point_error > best_sample_point_error) + { continue; + } best_sample_point_error = sample_point_error; best_baudrate_error = baudrate_error; @@ -224,7 +253,9 @@ static FError FCanCalcBittiming(FCanBaudrateConfig *bt_p, u32 target_baudrate, u best_brp = brp; if (baudrate_error == 0 && sample_point_error == 0) + { break; + } } if (best_baudrate_error) @@ -235,7 +266,7 @@ static FError FCanCalcBittiming(FCanBaudrateConfig *bt_p, u32 target_baudrate, u baudrate_error = (u32)v64; if (baudrate_error > CAN_CALC_MAX_ERROR) { - FCAN_ERROR("baudrate error"); + FCAN_ERROR("Baudrate error."); return FCAN_FAILURE; } } @@ -258,18 +289,22 @@ static FError FCanCalcBittiming(FCanBaudrateConfig *bt_p, u32 target_baudrate, u { /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ if (bt->sjw > btc->sjw_max) + { bt->sjw = btc->sjw_max; + } /* bt->sjw must not be higher than tseg2 */ if (tseg2 < bt->sjw) + { bt->sjw = tseg2; + } } bt->brp = best_brp; /* real baudrate */ - if (target_baudrate != FCAN_REF_CLOCK / (bt->brp * (CAN_CALC_SYNC_SEG + tseg1 + tseg2))) + if (target_baudrate != FCAN_CLK_FREQ_HZ / (bt->brp * (CAN_CALC_SYNC_SEG + tseg1 + tseg2))) { - FCAN_ERROR("target baudrate calculate timing failed"); + FCAN_ERROR("Target baudrate calculate timing failed."); return FCAN_FAILURE; } @@ -289,54 +324,54 @@ static u32 FCanGetDlcLen(u32 dlc) switch (dlc) { - case 1: - dlc_len = 1; - break; - case 2: - dlc_len = 2; - break; - case 3: - dlc_len = 3; - break; - case 4: - dlc_len = 4; - break; - case 5: - dlc_len = 5; - break; - case 6: - dlc_len = 6; - break; - case 7: - dlc_len = 7; - break; - case 8: - dlc_len = 8; - break; - case 9: - dlc_len = 12; - break; - case 10: - dlc_len = 16; - break; - case 11: - dlc_len = 20; - break; - case 12: - dlc_len = 24; - break; - case 13: - dlc_len = 32; - break; - case 14: - dlc_len = 48; - break; - case 15: - dlc_len = 64; - break; - default : - dlc_len = 0; - break; + case 1: + dlc_len = 1; + break; + case 2: + dlc_len = 2; + break; + case 3: + dlc_len = 3; + break; + case 4: + dlc_len = 4; + break; + case 5: + dlc_len = 5; + break; + case 6: + dlc_len = 6; + break; + case 7: + dlc_len = 7; + break; + case 8: + dlc_len = 8; + break; + case 9: + dlc_len = 12; + break; + case 10: + dlc_len = 16; + break; + case 11: + dlc_len = 20; + break; + case 12: + dlc_len = 24; + break; + case 13: + dlc_len = 32; + break; + case 14: + dlc_len = 48; + break; + case 15: + dlc_len = 64; + break; + default : + dlc_len = 0; + break; } return dlc_len; @@ -401,7 +436,7 @@ void FCanReset(FCanCtrl *instance_p) reg_value = FCAN_READ_REG32(config_p->base_address, FCAN_CTRL_OFFSET); if (reg_value & FCAN_CTRL_XFER_MASK) { - FCAN_ERROR("FT can is not in configration mode\n"); + FCAN_ERROR("Can is not in configration mode."); return; } @@ -444,7 +479,7 @@ FError FCanCfgInitialize(FCanCtrl *instance_p, const FCanConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FCAN_WARN("device is already initialized!!!"); + FCAN_WARN("Device is already initialized."); } /*Set default values and configuration data */ @@ -628,8 +663,8 @@ FError FCanSend(FCanCtrl *instance_p, FCanFrame *frame_p) if (frame_p->canid & CAN_EFF_FLAG) { /* Extended CAN id format */ - id = FCAN_IDR_ID2_GET(frame_p->canid & CAN_EFF_MASK); - id |= FCAN_IDR_ID1_GET((frame_p->canid & CAN_EFF_MASK) >> + id = FCAN_IDR_ID2_SET(frame_p->canid & CAN_EFF_MASK); + id |= FCAN_IDR_ID1_SET((frame_p->canid & CAN_EFF_MASK) >> (CAN_EFF_ID_BITS - CAN_SFF_ID_BITS)); /* The substibute remote TX request bit should be "1" @@ -672,10 +707,12 @@ FError FCanSend(FCanCtrl *instance_p, FCanFrame *frame_p) else { /* Standard CAN id format */ - id = FCAN_IDR_ID1_GET(frame_p->canid & CAN_SFF_MASK); + id = FCAN_IDR_ID1_SET(frame_p->canid & CAN_SFF_MASK); if (frame_p->canid & CAN_RTR_FLAG) + { id |= FCAN_IDR_SRR_MASK; + } FCAN_DEBUG("instance_p->use_canfd = %d, can_send_dlc = %d \n", instance_p->use_canfd, can_send_dlc); @@ -705,7 +742,7 @@ FError FCanSend(FCanCtrl *instance_p, FCanFrame *frame_p) } id |= dlc; - FCAN_DEBUG("can_send id = %#x\n", id); + FCAN_DEBUG("FCanSend id = %#x\n", id); FCAN_WRITE_REG32(base_address, FCAN_TX_FIFO_OFFSET, be32_to_cpu(id)); } @@ -728,10 +765,18 @@ FError FCanSend(FCanCtrl *instance_p, FCanFrame *frame_p) } /* triggers tranmission */ - FCAN_CLEARBIT(base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK); - FCAN_SETBIT(base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK | FCAN_CTRL_XFER_MASK); + if (FCAN_READ_REG32(base_address, FCAN_CTRL_OFFSET) & FCAN_CTRL_TXREQ_MASK) + { + FCAN_CLEARBIT(base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK); + FCAN_SETBIT(base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK | FCAN_CTRL_XFER_MASK); + return FCAN_SUCCESS; + } + else + { + FCAN_WARN("Monitoring mode cannot send message!!!"); + return FCAN_FAILURE; + } - return FCAN_SUCCESS; } /** @@ -777,9 +822,13 @@ static FError FCanSetTiming(FCanCtrl *instance_p, FCanBaudrateConfig *bittiming_ if (reg_val) { if (target_segment == FCAN_DATA_SEGMENT) + { FCAN_WRITE_REG32(base_address, FCAN_DAT_RATE_CTRL_OFFSET, reg_val); + } else + { FCAN_WRITE_REG32(base_address, FCAN_ARB_RATE_CTRL_OFFSET, reg_val); + } } else { @@ -805,7 +854,7 @@ static FError FCanSetTiming(FCanCtrl *instance_p, FCanBaudrateConfig *bittiming_ * @note this function is to set arb and data segment baudrate, according to the prop_seg, * phase_seg1, phase_seg2 ,brp and sjw parameters, users can use this function to set can baudrate. * A formula to calculate baudrate is: - * baudrate = FCAN_REF_CLOCK/(brp*(sjw+prop_seg+phase_seg1++phase_seg2)) + * baudrate = FCAN_CLK_FREQ_HZ/(brp*(sjw+prop_seg+phase_seg1++phase_seg2)) * sample point = (sjw+prop_seg+phase_seg1)/(sjw+prop_seg+phase_seg1++phase_seg2) * Recommended sample point : * 75.0% : baudrate > 800000 @@ -833,7 +882,7 @@ FError FCanBaudrateSet(FCanCtrl *instance_p, FCanBaudrateConfig *baudrate_p) FCAN_ERROR("FCanBaudrateSet FCAN_DATA_SEGMENT baudrate = %d invalid", baudrate); return FCAN_INVAL_PARAM; } -#elif defined(CONFIG_TARGET_E2000) +#elif defined(CONFIG_TARGET_E2000) || defined(TARDIGRADE) if ((segment == FCAN_ARB_SEGMENT) && ((baudrate > FCAN_BAUDRATE_1000K) || (baudrate < FCAN_BAUDRATE_10K))) { FCAN_ERROR("FCanBaudrateSet FCAN_ARB_SEGMENT baudrate = %d invalid", baudrate); @@ -894,7 +943,6 @@ FError FCanEnable(FCanCtrl *instance_p, boolean enable) FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); uintptr base_addr = instance_p->config.base_address; - if (enable == TRUE) { FCAN_SETBIT(base_addr, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK); @@ -930,24 +978,24 @@ FError FCanIdMaskFilterSet(FCanCtrl *instance_p, FCanIdMaskConfig *id_mask_p) switch (filter_index) { - case 0: - id_reg_offset = FCAN_ACC_ID0_OFFSET; - mask_reg_offset = FCAN_ACC_ID0_MASK_OFFSET; - break; - case 1: - id_reg_offset = FCAN_ACC_ID1_OFFSET; - mask_reg_offset = FCAN_ACC_ID1_MASK_OFFSET; - break; - case 2: - id_reg_offset = FCAN_ACC_ID2_OFFSET; - mask_reg_offset = FCAN_ACC_ID2_MASK_OFFSET; - break; - case 3: - id_reg_offset = FCAN_ACC_ID3_OFFSET; - mask_reg_offset = FCAN_ACC_ID3_MASK_OFFSET; - break; - default: - return FCAN_FAILURE; + case 0: + id_reg_offset = FCAN_ACC_ID0_OFFSET; + mask_reg_offset = FCAN_ACC_ID0_MASK_OFFSET; + break; + case 1: + id_reg_offset = FCAN_ACC_ID1_OFFSET; + mask_reg_offset = FCAN_ACC_ID1_MASK_OFFSET; + break; + case 2: + id_reg_offset = FCAN_ACC_ID2_OFFSET; + mask_reg_offset = FCAN_ACC_ID2_MASK_OFFSET; + break; + case 3: + id_reg_offset = FCAN_ACC_ID3_OFFSET; + mask_reg_offset = FCAN_ACC_ID3_MASK_OFFSET; + break; + default: + return FCAN_FAILURE; } if (id_mask_p->type == FCAN_STANDARD_FRAME) @@ -1010,20 +1058,39 @@ FError FCanInterruptEnable(FCanCtrl *instance_p, FCanIntrEventType event_type) switch (event_type) { - case FCAN_INTR_EVENT_SEND: - reg_val |= FCAN_INTR_TEIE_MASK; - break; + case FCAN_INTR_EVENT_SEND: + reg_val |= FCAN_INTR_TEIE_MASK; + break; - case FCAN_INTR_EVENT_RECV: - reg_val |= FCAN_INTR_REIE_MASK; - break; + case FCAN_INTR_EVENT_RECV: + reg_val |= FCAN_INTR_REIE_MASK; + break; - case FCAN_INTR_EVENT_ERROR: - reg_val |= FCAN_INTR_EIE_MASK; - break; + case FCAN_INTR_EVENT_ERROR: + reg_val |= FCAN_INTR_EIE_MASK; + break; - default: - break; + case FCAN_INTR_EVENT_BUSOFF: + reg_val |= FCAN_INTR_BOIE_MASK; + break; + + case FCAN_INTR_EVENT_PERROE: + reg_val |= FCAN_INTR_PEIE_MASK; + break; + + case FCAN_INTR_EVENT_PWARN: + reg_val |= FCAN_INTR_PWIE_MASK; + break; + + case FCAN_INTR_EVENT_FIFOFULL: + reg_val |= FCAN_INTR_RFIE_MASK; + break; + + case FCAN_INTR_EVENT_FIFOEMPTY: + reg_val |= FCAN_INTR_TFIE_MASK; + break; + default: + break; } FCAN_WRITE_REG32(base_addr, FCAN_INTR_OFFSET, reg_val); @@ -1057,4 +1124,30 @@ FError FCanFdEnable(FCanCtrl *instance_p, boolean enable) } return FCAN_SUCCESS; -} \ No newline at end of file +} + +/** + * @name: FCanSetMode + * @msg: Set the transmit mode, Monitor or Normal + * @param {FCanCtrl} *instance_p, instance of FCanCtrl controller + * @param {u32} tran_mode,parameters of target mode,0 Monitor mode,1 Normal mode + * @return err code information, FCAN_SUCCESS indicates success,others indicates failed + */ +FError FCanSetMode(FCanCtrl *instance_p, u32 tran_mode) +{ + FASSERT(instance_p != NULL); + FASSERT(FT_COMPONENT_IS_READY == instance_p->is_ready); + uintptr base_addr = instance_p->config.base_address; + + if (tran_mode == FCAN_PROBE_MONITOR_MODE) + { + FCAN_CLEARBIT(base_addr, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK); + } + if (tran_mode == FCAN_PROBE_NORMAL_MODE) + { + FCAN_SETBIT(base_addr, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK); + } + + return FCAN_SUCCESS; +} + diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.h b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.h index d35076fd74..b036f435d0 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.h +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan.h @@ -14,16 +14,19 @@ * FilePath: fcan.h * Date: 2021-04-27 15:08:44 * LastEditTime: 2022-02-18 08:29:25 - * Description:  This files is for + * Description:  This files is for the can function related definitions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release + * 1.1 wangxiaodong 2022/9/23 improve functions + * 1.2 zhangyan 2022/12/7 improve functions */ -#ifndef FT_CAN_H -#define FT_CAN_H +#ifndef FCAN_H +#define FCAN_H #include "ftypes.h" #include "ferror_code.h" @@ -31,11 +34,21 @@ #include "fkernel.h" #include "fcan_hw.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef enum { - FCAN_INTR_EVENT_SEND = 0, /* Handler type for frame sending interrupt */ - FCAN_INTR_EVENT_RECV = 1, /* Handler type for frame reception interrupt */ - FCAN_INTR_EVENT_ERROR, /* Handler type for error interrupt */ + FCAN_INTR_EVENT_SEND = 0, /* Handler type for frame sending interrupt */ + FCAN_INTR_EVENT_RECV = 1, /* Handler type for frame reception interrupt */ + FCAN_INTR_EVENT_ERROR = 2, /* Handler type for error interrupt */ + FCAN_INTR_EVENT_BUSOFF = 3, /* Handler type for bus off interrupt */ + FCAN_INTR_EVENT_PERROE = 4, /* Handler type for passion error interrupt */ + FCAN_INTR_EVENT_PWARN = 5, /* Handler type for passion warn interrupt */ + FCAN_INTR_EVENT_FIFOFULL = 6, /* Handler type for rx fifo register full */ + FCAN_INTR_EVENT_FIFOEMPTY = 7,/* Handler type for tx fifo register empty */ FCAN_INTR_EVENT_NUM } FCanIntrEventType; @@ -75,6 +88,10 @@ typedef enum #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ #define CAN_CALC_SYNC_SEG 1 +/*Transmit mode*/ +#define FCAN_PROBE_MONITOR_MODE 0 /* Monitor mode */ +#define FCAN_PROBE_NORMAL_MODE 1 /* Normal mode */ + /* can segment type */ typedef enum { @@ -199,7 +216,7 @@ typedef struct } FCanCtrl; /* get default configuration of specific can id */ -const FCanConfig *FCanLookupConfig(FCanInstance instance_id); +const FCanConfig *FCanLookupConfig(u32 instance_id); /* reset a specific can instance */ void FCanReset(FCanCtrl *instance_p); @@ -246,4 +263,11 @@ FError FCanInterruptEnable(FCanCtrl *instance_p, FCanIntrEventType event_type); /* Enable or disable can fd */ FError FCanFdEnable(FCanCtrl *instance_p, boolean enable); +/* Set the transmit mode */ +FError FCanSetMode(FCanCtrl *instance_p, u32 tran_mode); + +#ifdef __cplusplus +} +#endif + #endif // !FT_CAN_H diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_g.c b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_g.c index 62d126a570..b1a59bf2bd 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_g.c +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_g.c @@ -14,33 +14,34 @@ * FilePath: fcan_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:45 - * Description:  This files is for + * Description:  This files is for the can default configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release */ - +#include "sdkconfig.h" #include "fcan.h" #include "fparameters.h" -const FCanConfig FCanConfigTbl[FCAN_INSTANCE_NUM] = +const FCanConfig FCanConfigTbl[FCAN_NUM] = { { - .instance_id = FCAN_INSTANCE_0, /* Id of device */ - .base_address = FCAN0_BASEADDR, /* Can base Address */ - .irq_num = FCAN0_IRQNUM, + .instance_id = FCAN0_ID, /* Id of device */ + .base_address = FCAN0_BASE_ADDR, /* Can base Address */ + .irq_num = FCAN0_IRQ_NUM, }, { - .instance_id = FCAN_INSTANCE_1, /* Id of device */ - .base_address = FCAN1_BASEADDR, /* Can base Address */ - .irq_num = FCAN1_IRQNUM, + .instance_id = FCAN1_ID, /* Id of device */ + .base_address = FCAN1_BASE_ADDR, /* Can base Address */ + .irq_num = FCAN1_IRQ_NUM, }, #if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) { - .instance_id = FCAN_INSTANCE_2, /* Id of device */ - .base_address = FCAN2_BASEADDR, /* Can base Address */ + .instance_id = FCAN2_ID, /* Id of device */ + .base_address = FCAN2_BASE_ADDR, /* Can base Address */ .irq_num = FCAN2_IRQNUM, } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.c b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.c index dedaa33077..b06da31ebc 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.c @@ -14,11 +14,12 @@ * FilePath: fcan_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:28:50 - * Description:  This files is for + * Description:  This files is for the can register related functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release */ @@ -37,31 +38,31 @@ void FCanDump(uintptr base_addr) { - printf("Off[0x%x]: FCAN_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_CTRL_OFFSET)); - printf("Off[0x%x]: FCAN_INTR_OFFSET = 0x%08x\r\n", base_addr + FCAN_INTR_OFFSET, FCAN_READ_REG32(base_addr, FCAN_INTR_OFFSET)); - printf("Off[0x%x]: FCAN_ARB_RATE_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_ARB_RATE_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ARB_RATE_CTRL_OFFSET)); - printf("Off[0x%x]: FCAN_DAT_RATE_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_DAT_RATE_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_DAT_RATE_CTRL_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID0_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID0_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID0_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID1_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID1_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID1_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID2_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID2_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID2_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID3_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID3_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID3_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID0_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID0_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID0_MASK_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID1_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID1_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID1_MASK_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID2_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID2_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID2_MASK_OFFSET)); - printf("Off[0x%x]: FCAN_ACC_ID3_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID3_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID3_MASK_OFFSET)); - printf("Off[0x%x]: FCAN_XFER_STS_OFFSET = 0x%08x\r\n", base_addr + FCAN_XFER_STS_OFFSET, FCAN_READ_REG32(base_addr, FCAN_XFER_STS_OFFSET)); - printf("Off[0x%x]: FCAN_ERR_CNT_OFFSET = 0x%08x\r\n", base_addr + FCAN_ERR_CNT_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ERR_CNT_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_CTRL_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_INTR_OFFSET = 0x%08x\r\n", base_addr + FCAN_INTR_OFFSET, FCAN_READ_REG32(base_addr, FCAN_INTR_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ARB_RATE_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_ARB_RATE_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ARB_RATE_CTRL_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_DAT_RATE_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_DAT_RATE_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_DAT_RATE_CTRL_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID0_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID0_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID0_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID1_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID1_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID1_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID2_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID2_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID2_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID3_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID3_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID3_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID0_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID0_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID0_MASK_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID1_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID1_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID1_MASK_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID2_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID2_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID2_MASK_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ACC_ID3_MASK_OFFSET = 0x%08x\r\n", base_addr + FCAN_ACC_ID3_MASK_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ACC_ID3_MASK_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_XFER_STS_OFFSET = 0x%08x\r\n", base_addr + FCAN_XFER_STS_OFFSET, FCAN_READ_REG32(base_addr, FCAN_XFER_STS_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_ERR_CNT_OFFSET = 0x%08x\r\n", base_addr + FCAN_ERR_CNT_OFFSET, FCAN_READ_REG32(base_addr, FCAN_ERR_CNT_OFFSET)); - printf("Off[0x%x]: FCAN_FIFO_CNT_OFFSET = 0x%08x\r\n", base_addr + FCAN_FIFO_CNT_OFFSET, FCAN_READ_REG32(base_addr, FCAN_FIFO_CNT_OFFSET)); - printf("Off[0x%x]: FCAN_DMA_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_DMA_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_DMA_CTRL_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_FIFO_CNT_OFFSET = 0x%08x\r\n", base_addr + FCAN_FIFO_CNT_OFFSET, FCAN_READ_REG32(base_addr, FCAN_FIFO_CNT_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_DMA_CTRL_OFFSET = 0x%08x\r\n", base_addr + FCAN_DMA_CTRL_OFFSET, FCAN_READ_REG32(base_addr, FCAN_DMA_CTRL_OFFSET)); - printf("Off[0x%x]: FCAN_XFER_EN_OFFSET = 0x%08x\r\n", base_addr + FCAN_XFER_EN_OFFSET, FCAN_READ_REG32(base_addr, FCAN_XFER_EN_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_XFER_EN_OFFSET = 0x%08x\r\n", base_addr + FCAN_XFER_EN_OFFSET, FCAN_READ_REG32(base_addr, FCAN_XFER_EN_OFFSET)); - printf("Off[0x%x]: FCAN_FRM_INFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_FRM_INFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_FRM_INFO_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_FRM_INFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_FRM_INFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_FRM_INFO_OFFSET)); - printf("Off[0x%x]: FCAN_TX_FIFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_TX_FIFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_TX_FIFO_OFFSET)); - printf("Off[0x%x]: FCAN_RX_FIFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_RX_FIFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_RX_FIFO_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_TX_FIFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_TX_FIFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_TX_FIFO_OFFSET)); + FCAN_DEBUG("Off[0x%x]: FCAN_RX_FIFO_OFFSET = 0x%08x\r\n", base_addr + FCAN_RX_FIFO_OFFSET, FCAN_READ_REG32(base_addr, FCAN_RX_FIFO_OFFSET)); - printf("\r\n"); + FCAN_DEBUG("\r\n"); } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.h b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.h index 1117d962bc..0f59b3f2be 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_hw.h @@ -14,21 +14,29 @@ * FilePath: fcan_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:29:05 - * Description:  This files is for + * Description:  This files is for the can register related definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release + * 1.1 zhangyan 2022/12/7 improve functions */ -#ifndef FT_CAN_HW_H -#define FT_CAN_HW_H +#ifndef FCAN_HW_H +#define FCAN_HW_H +#include "fparameters.h" #include "ftypes.h" #include "fio.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /***ft CAN REGISTER offset*/ #define FCAN_CTRL_OFFSET 0x00 /* Global control register */ #define FCAN_INTR_OFFSET 0x04 /* Interrupt register */ @@ -89,7 +97,7 @@ #define FCAN_INTR_TFIC_MASK BIT(20) /* TX FIFO empty interrupt clear*/ #define FCAN_INTR_REIC_MASK BIT(21) /* RX frame end interrupt clear*/ #define FCAN_INTR_TEIC_MASK BIT(22) /* TX frame end interrupt clear*/ -#define FCAN_INTR_EIC_MASK BIT(23) /* Error interrupt clear*/ +#define FCAN_INTR_EIC_MASK BIT(23) /* Error interrupt clear*/ #define FCAN_INTR_BORIS_MASK BIT(24) #define FCAN_INTR_PWRIS_MASK BIT(25) #define FCAN_INTR_PERIS_MASK BIT(26) @@ -131,7 +139,7 @@ #define FCAN_FIFO_CNT_TFN_GET(x) GET_REG32_BITS((x), 22, 16) #define FCAN_FIFO_CNT_TFN_SET(x) SET_REG32_BITS((x), 22, 16) -#define FCAN_IDR_ID1_SHIFT 21 /* Standard Messg Identifier */ +#define FCAN_IDR_ID1_SHIFT 21 /* Standard Message Identifier */ #define FCAN_IDR_SDLC_SHIFT 14 #define FCANFD_IDR_EDLC_SHIFT 24 #define FCAN_IDR_EDLC_SHIFT 26 @@ -186,7 +194,7 @@ #define FCAN_DATA_BRP_MAX 512 #define FCAN_DATA_BRP_INC 1 -#elif defined(CONFIG_TARGET_E2000) +#elif defined(CONFIG_TARGET_E2000) || defined(TARDIGRADE) #define FCAN_ARB_TSEG1_MIN 1 #define FCAN_ARB_TSEG1_MAX 16 @@ -235,7 +243,6 @@ #define FCAN_CLEARBIT(base_addr, reg_offset, data) FtClearBit32((base_addr) + (u32)(reg_offset), (u32)(data)) - #define FCAN_TX_FIFO_FULL(instance_p) (FCAN_FIFO_DEPTH == FCAN_FIFO_CNT_TFN_GET(FCAN_READ_REG32(instance_p->config.base_address, FCAN_FIFO_CNT_OFFSET))) #define FCAN_RX_FIFO_EMPTY(instance_p) (0 == FCAN_FIFO_CNT_RFN_GET(FCAN_READ_REG32(instance_p->config.base_address, FCAN_FIFO_CNT_OFFSET))) @@ -243,4 +250,8 @@ void FCanDump(uintptr base_addr); +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_intr.c b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_intr.c index a792448e73..2f5c40c546 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_intr.c @@ -14,14 +14,15 @@ * FilePath: fcan_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:29:10 - * Description:  This files is for + * Description:  This files is for the can interrupt functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first release + * 1.1 zhangyan 2022/12/7 improve functions */ -#include "finterrupt.h" #include "fcan.h" #include "fcan_hw.h" #include "fassert.h" @@ -80,7 +81,7 @@ void FCanIntrHandler(s32 vector, void *args) return; } - /* Check for the type of error interrupt and Processing it */ + /* Check for the type of interrupt and Processing it */ if (irq_status & FCAN_INTR_TEIS_MASK) { irq_status &= ~FCAN_INTR_REIS_MASK; @@ -93,36 +94,62 @@ void FCanIntrHandler(s32 vector, void *args) FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_SEND); } - if (irq_status & (FCAN_INTR_EIS_MASK | FCAN_INTR_RFIS_MASK | FCAN_INTR_TFIS_MASK | + if (irq_status & (FCAN_INTR_EIS_MASK | FCAN_INTR_RFIS_MASK | FCAN_INTR_TFIS_MASK | FCAN_INTR_BOIS_MASK | FCAN_INTR_PEIS_MASK | FCAN_INTR_PWIS_MASK)) { - FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_ERROR); - FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, - (FCAN_INTR_EIC_MASK | FCAN_INTR_RFIC_MASK | FCAN_INTR_BOIC_MASK | - FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK)); + (FCAN_INTR_EIC_MASK | FCAN_INTR_RFIC_MASK | FCAN_INTR_BOIC_MASK | + FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK | FCAN_INTR_TFIC_MASK)); /* Check for rx fifo full interrupt and output error information */ if (irq_status & FCAN_INTR_RFIS_MASK) { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOFULL); FCAN_ERROR("rx_fifo is full!!!"); /* disable rx fifo full interrupt */ FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_RFIE_MASK); } - if (irq_status & FCAN_INTR_TFIS_MASK) { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOEMPTY); FCAN_ERROR("tx_fifo is empty!!!"); /* disable tx fifo empty interrupt */ FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_TFIE_MASK); } + if (irq_status & FCAN_INTR_EIS_MASK) + { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_ERROR); + FCAN_ERROR("Error occurred!!!"); + /* disable error interrupt */ + FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_EIE_MASK); + } + if (irq_status & FCAN_INTR_BOIS_MASK) + { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_BUSOFF); + FCAN_ERROR("Bus off!!!"); + /* disable busoff interrupt */ + FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_BOIE_MASK); + } + if (irq_status & FCAN_INTR_PEIS_MASK) + { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PERROE); + FCAN_ERROR("Passive error occurred!!!"); + /* disable passive error interrupt */ + FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_PEIE_MASK); + } + if (irq_status & FCAN_INTR_PWIS_MASK) + { + FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PWARN); + FCAN_ERROR("Passive warning!!!"); + /* disable passive warning interrupt */ + FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_PWIE_MASK); + } } if (irq_status & FCAN_INTR_REIS_MASK) { FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK); FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_REIC_MASK); - FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK); FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_RECV); } } diff --git a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_sinit.c b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_sinit.c index 15dbb27ba0..0b01226ee4 100644 --- a/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/can/fcan/fcan_sinit.c @@ -14,11 +14,12 @@ * FilePath: fcan_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:29:15 - * Description:  This files is for + * Description:  This files is for getting default configuration of specific can instance_id * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/5/26 first releases */ @@ -26,21 +27,21 @@ #include "fparameters.h" #include "fassert.h" -extern const FCanConfig FCanConfigTbl[FCAN_INSTANCE_NUM]; +extern const FCanConfig FCanConfigTbl[FCAN_NUM]; /** * @name: FCanLookupConfig * @msg: get default configuration of specific can instance_id. - * @param {FCanInstance} instance_id, instance id of Can controller + * @param {u32} instance_id, instance id of Can controller * @return {FCanConfig*} Default configuration parameters of Can */ -const FCanConfig *FCanLookupConfig(FCanInstance instance_id) +const FCanConfig *FCanLookupConfig(u32 instance_id) { - FASSERT(instance_id < FCAN_INSTANCE_NUM); + FASSERT(instance_id < FCAN_NUM); const FCanConfig *pconfig = NULL; u32 index; - for (index = 0; index < (u32)FCAN_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FCAN_NUM; index++) { if (FCanConfigTbl[index].instance_id == instance_id) { @@ -48,5 +49,5 @@ const FCanConfig *FCanLookupConfig(FCanInstance instance_id) break; } } - return (FCanConfig *)pconfig; + return (const FCanConfig *)pconfig; } diff --git a/bsp/phytium/libraries/standalone/drivers/dma/Kconfig b/bsp/phytium/libraries/standalone/drivers/dma/Kconfig index 16336f66e1..9ed7f94848 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/dma/Kconfig @@ -2,9 +2,9 @@ config ENABLE_FGDMA bool prompt "Use FGDMA" - default n + default n config ENABLE_FDDMA bool prompt "Use FDDMA" - default n + default n \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.c index 494af32fde..31fc660b65 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.c @@ -14,12 +14,12 @@ * FilePath: fddma.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for ddma interface implementation + * Description:  This file is for ddma interface implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ @@ -65,7 +65,7 @@ FError FDdmaCfgInitialization(FDdma *const instance, const FDdmaConfig *input_co if (FT_COMPONENT_IS_READY == instance->is_ready) { - FDDMA_WARN("device is already initialized!!!"); + FDDMA_WARN("The device has been initialized !!!"); } FDdmaDeInitialization(instance); @@ -75,7 +75,7 @@ FError FDdmaCfgInitialization(FDdma *const instance, const FDdmaConfig *input_co if (FDDMA_SUCCESS == ret) { instance->is_ready = FT_COMPONENT_IS_READY; - FDDMA_INFO("ddma@0x%x init success !!!", base_addr); + FDDMA_INFO("ddma@0x%x initialized successfully !!!", base_addr); } return ret; @@ -95,7 +95,7 @@ FError FDdmaStart(FDdma *const instance) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } @@ -118,7 +118,7 @@ FError FDdmaStop(FDdma *const instance) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } @@ -142,7 +142,7 @@ void FDdmaDeInitialization(FDdma *const instance) { if (instance->bind_status & BIT(chan)) { - FDDMA_WARN("channel %d has not been unbind", chan); + FDDMA_WARN("Channel %d is not yet unbound", chan); } } @@ -168,34 +168,34 @@ FError FDdmaAllocateChan(FDdma *const instance, FDdmaChan *const dma_chan, const if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } if ((TRUE == dma_chan->is_used) || (BIT(chan_idx) & instance->bind_status)) { - FDDMA_ERROR("chan-%d is already is use !!!", chan_idx); + FDDMA_ERROR("Channel -%d has already been used !!!", chan_idx); return FDDMA_ERR_CHAN_BINDED; } if (FDdmaIsChanRunning(base_addr, chan_idx)) { - FDDMA_ERROR("chan-%d is already running !!!", chan_idx); + FDDMA_ERROR("Channel -%d is running !!!", chan_idx); return FDDMA_ERR_CHAN_BINDED; } if (dma_chan_config->ddr_addr % FDDMA_DDR_ADDR_ALIGMENT) { - FDDMA_ERROR("ddr addr 0x%x must align with %d bytes", + FDDMA_ERROR("DDR addr 0x%x must be aligned with %d bytes", dma_chan_config->ddr_addr, FDDMA_DDR_ADDR_ALIGMENT); return FDDMA_ERR_INVALID_DDR_ADDR; } if ((FDDMA_MAX_TRANSFER_LEN < dma_chan_config->trans_len) || - (FDDMA_MIN_TRANSFER_LEN > dma_chan_config->trans_len) || - (0 != dma_chan_config->trans_len % FDDMA_MIN_TRANSFER_LEN)) + (FDDMA_MIN_TRANSFER_LEN > dma_chan_config->trans_len) || + (0 != dma_chan_config->trans_len % FDDMA_MIN_TRANSFER_LEN)) { - FDDMA_ERROR("invalid transfer size %d Bytes !!!", dma_chan_config->trans_len); + FDDMA_ERROR("Invalid transfer size %d bytes !!!", dma_chan_config->trans_len); return FDDMA_ERR_INVALID_TRANS_SIZE; } @@ -203,13 +203,15 @@ FError FDdmaAllocateChan(FDdma *const instance, FDdmaChan *const dma_chan, const instance->chan[chan_idx] = dma_chan; if (&(dma_chan->config) != dma_chan_config) + { dma_chan->config = *dma_chan_config; + } FDdmaStop(instance); /* disable irq */ if (FDDMA_SUCCESS != FDdmaDisableChan(base_addr, chan_idx)) { - FDDMA_ERROR("disable DDMA@0x%x channel %d failed !!!", base_addr, chan_idx); + FDDMA_ERROR("Failed to disable DDMA@0x%x channel %d !!!", base_addr, chan_idx); return FDDMA_ERR_WAIT_TIMEOUT; } @@ -235,10 +237,10 @@ FError FDdmaAllocateChan(FDdma *const instance, FDdmaChan *const dma_chan, const FDdmaSetChanDirection(base_addr, chan_idx, (FDDMA_CHAN_REQ_RX == dma_chan->config.req_mode) ? TRUE : FALSE); - FDDMA_INFO("chan-%d ddr @0x%x", chan_idx, FDDMA_CHAN_DDR_LOW_ADDR_OFFSET(chan_idx)); + FDDMA_INFO("channel-%d ddr @0x%x", chan_idx, FDDMA_CHAN_DDR_LOW_ADDR_OFFSET(chan_idx)); FDDMA_INFO("ddr addr: 0x%x", FDdmaReadReg(base_addr, FDDMA_CHAN_DDR_LOW_ADDR_OFFSET(chan_idx))); FDDMA_INFO("dev addr: 0x%x", FDdmaReadReg(base_addr, FDDMA_CHAN_DEV_ADDR_OFFSET(chan_idx))); - FDDMA_INFO("trans len: %d", FDdmaReadReg(base_addr, FDDMA_CHAN_TS_OFFSET(chan_idx))); + FDDMA_INFO("transfer len: %d", FDdmaReadReg(base_addr, FDDMA_CHAN_TS_OFFSET(chan_idx))); FDdmaSetChanTimeout(base_addr, chan_idx, 0xffff); FDdmaEnableChanIrq(base_addr, chan_idx); @@ -247,7 +249,7 @@ FError FDdmaAllocateChan(FDdma *const instance, FDdmaChan *const dma_chan, const { instance->bind_status |= BIT(chan_idx); dma_chan->is_used = TRUE; - FDDMA_INFO("allocate channel %d", chan_idx); + FDDMA_INFO("Allocate channel %d", chan_idx); } return ret; @@ -269,13 +271,13 @@ FError FDdmaDellocateChan(FDdmaChan *const dma_chan) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } if (FDDMA_SUCCESS != FDdmaDisableChan(base_addr, chan_idx)) { - FDDMA_ERROR("disable DDMA@0x%x channel %d failed !!!", base_addr, chan_idx); + FDDMA_ERROR("Failed to disable DDMA@0x%x channel %d !!!", base_addr, chan_idx); return FDDMA_ERR_WAIT_TIMEOUT; } @@ -285,7 +287,7 @@ FError FDdmaDellocateChan(FDdmaChan *const dma_chan) ret = FDdmaDisableChan(base_addr, chan_idx); if (FDDMA_SUCCESS != ret) /* disable channel */ { - FDDMA_ERROR("disable ddma@%p channel %d failed !!!", base_addr, chan_idx); + FDDMA_ERROR("Failure to disable ddma@%p channel %d !!!", base_addr, chan_idx); return ret; } @@ -294,7 +296,7 @@ FError FDdmaDellocateChan(FDdmaChan *const dma_chan) instance->bind_status &= ~BIT(chan_idx); /* set bind status */ instance->chan[chan_idx] = NULL; - FDDMA_INFO("deallocate channel %d", chan_idx); + FDDMA_INFO("DeAllocate channels %d", chan_idx); memset(dma_chan, 0, sizeof(*dma_chan)); return ret; @@ -315,7 +317,7 @@ FError FDdmaActiveChan(FDdmaChan *const dma_chan) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } @@ -332,7 +334,7 @@ FError FDdmaDeactiveChan(FDdmaChan *const dma_chan) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FDDMA_ERROR("dma instance not init !!!"); + FDDMA_ERROR("The Dma instance is not initialized !!!"); return FDDMA_ERR_NOT_INIT; } @@ -355,7 +357,7 @@ static FError FDdmaReset(FDdma *const instance) if (0 != instance->bind_status) { - FDDMA_WARN("some channel not yet un-bind !!!"); + FDDMA_WARN("Some channels are not yet unbound !!!"); } FDdmaDisable(base_addr); /* disable ddma */ @@ -369,7 +371,7 @@ static FError FDdmaReset(FDdma *const instance) ret = FDdmaDisableChan(base_addr, chan); if (FDDMA_SUCCESS != ret) { - FDDMA_ERROR("disable ddma@%p channel %d failed !!!", base_addr, chan); + FDDMA_ERROR("Failure to disable ddma@%p channel %d !!!", base_addr, chan); break; } } diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.h b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.h index 486876a698..5529a0c1e1 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.h +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma.h @@ -14,16 +14,19 @@ * FilePath: fddma.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for ddma interface definition + * Description:  This file is for ddma interface definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ -#ifndef DRIVER_FDDMA_H -#define DRIVER_FDDMA_H +#ifndef FDDMA_H +#define FDDMA_H + +#include "ftypes.h" +#include "ferror_code.h" #ifdef __cplusplus extern "C" @@ -31,9 +34,6 @@ extern "C" #endif /***************************** Include Files *********************************/ -#include "ftypes.h" -#include "ferror_code.h" - /************************** Constant Definitions *****************************/ typedef enum { diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_g.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_g.c index 4204d9d23e..6bcce37b1f 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_g.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_g.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.c index dfbe76576e..f66ca8aaf5 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ @@ -91,14 +91,14 @@ void FDdmaSoftwareReset(uintptr base_addr) u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CTL_OFFSET); reg_val |= FDDMA_CTL_SRST; FDdmaWriteReg(base_addr, FDDMA_CTL_OFFSET, reg_val); - FDDMA_DEBUG("ddma @%p software reset start : 0x%x", base_addr, FDdmaReadReg(base_addr, FDDMA_CTL_OFFSET)); + FDDMA_DEBUG("ddma @%p soft reset start : 0x%x", base_addr, FDdmaReadReg(base_addr, FDDMA_CTL_OFFSET)); while (--delay > 0) /* wait a while to do reset */ ; reg_val &= ~FDDMA_CTL_SRST; FDdmaWriteReg(base_addr, FDDMA_CTL_OFFSET, reg_val); /* exit from software reset */ - FDDMA_DEBUG("ddma @%p software reset end : 0x%x", base_addr, FDdmaReadReg(base_addr, FDDMA_CTL_OFFSET)); + FDDMA_DEBUG("ddma @%p soft reset end : 0x%x", base_addr, FDdmaReadReg(base_addr, FDDMA_CTL_OFFSET)); return; } @@ -139,7 +139,7 @@ void FDdmaEnableGlobalIrq(uintptr base_addr) */ void FDdmaDisableChanIrq(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_MASK_INTR_OFFSET); reg_val |= FDDMA_MASK_EN_CHAN_INTR(chan); FDdmaWriteReg(base_addr, FDDMA_MASK_INTR_OFFSET, reg_val); @@ -155,7 +155,7 @@ void FDdmaDisableChanIrq(uintptr base_addr, u32 chan) */ void FDdmaEnableChanIrq(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_MASK_INTR_OFFSET); reg_val &= ~FDDMA_MASK_EN_CHAN_INTR(chan); /* write 0 and enable */ FDdmaWriteReg(base_addr, FDDMA_MASK_INTR_OFFSET, reg_val); @@ -171,7 +171,7 @@ void FDdmaEnableChanIrq(uintptr base_addr, u32 chan) */ FError FDdmaDisableChan(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); int delay = 1000; u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); reg_val &= ~FDDMA_CHAN_CTL_EN; @@ -182,11 +182,13 @@ FError FDdmaDisableChan(uintptr base_addr, u32 chan) { reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); if (delay-- <= 0) + { break; + } } while (reg_val & FDDMA_CHAN_CTL_EN); - FDDMA_DEBUG("ddma @%p chan %d disabled : 0x%x", base_addr, chan, FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan))); + FDDMA_DEBUG("ddma@ %p channel %d is disabled : 0x%x", base_addr, chan, FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan))); return (delay > 0) ? FDDMA_SUCCESS : FDDMA_ERR_WAIT_TIMEOUT; } @@ -199,7 +201,7 @@ FError FDdmaDisableChan(uintptr base_addr, u32 chan) */ void FDdmaEnableChan(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); reg_val |= FDDMA_CHAN_CTL_EN; FDdmaWriteReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan), reg_val); @@ -216,7 +218,7 @@ void FDdmaEnableChan(uintptr base_addr, u32 chan) */ void FDdmaClearChanIrq(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); /* write 1 to clear irq status of channel */ FDdmaWriteReg(base_addr, FDDMA_STA_OFFSET, FDDMA_STA_CHAN_REQ_DONE(chan)); } @@ -230,12 +232,14 @@ void FDdmaClearChanIrq(uintptr base_addr, u32 chan) */ void FDdmaResetChan(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); int delay = 1000; u32 reg_val; if (FDdmaIsChanRunning(base_addr, chan)) /* disable channel if running */ + { (void)FDdmaDisableChan(base_addr, chan); + } reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); reg_val |= FDDMA_CHAN_CTL_SRST; @@ -246,7 +250,7 @@ void FDdmaResetChan(uintptr base_addr, u32 chan) reg_val &= ~FDDMA_CHAN_CTL_SRST; FDdmaWriteReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan), reg_val); - FDDMA_DEBUG("chan reset done, ctrl: 0x%x", FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan))); + FDDMA_DEBUG("Channel reset done, ctrl: 0x%x", FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan))); return; } @@ -259,7 +263,7 @@ void FDdmaResetChan(uintptr base_addr, u32 chan) */ boolean FDdmaIsChanRunning(uintptr base_addr, u32 chan) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); return (FDDMA_CHAN_CTL_EN & reg_val) ? TRUE : FALSE; } @@ -274,8 +278,8 @@ boolean FDdmaIsChanRunning(uintptr base_addr, u32 chan) */ void FDdmaSetChanSelection(uintptr base_addr, u32 chan, u32 slave_id) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); - FASSERT_MSG((FDDMA_MAX_SLAVE_ID >= slave_id), "invalid slave id %d", slave_id); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); + FASSERT_MSG((FDDMA_MAX_SLAVE_ID >= slave_id), "Invalid slave id %d", slave_id); u32 reg_val; if (FDDMA_CHAN_4 > chan) @@ -285,7 +289,7 @@ void FDdmaSetChanSelection(uintptr base_addr, u32 chan, u32 slave_id) reg_val |= FDDMA_CHAN_0_3_SEL(chan, slave_id); reg_val |= FDDMA_CHAN_0_3_SEL_EN(chan); FDdmaWriteReg(base_addr, FDDMA_CHAN_0_3_CFG_OFFSET, reg_val); - FDDMA_DEBUG("ddma@%p set chan-%d slave id-%d, 0x%x", base_addr, chan, slave_id, FDdmaReadReg(base_addr, FDDMA_CHAN_0_3_CFG_OFFSET)); + FDDMA_DEBUG("ddma%p sets the slaveid of chan-%d to %d, 0x%x", base_addr, chan, slave_id, FDdmaReadReg(base_addr, FDDMA_CHAN_0_3_CFG_OFFSET)); } else { @@ -294,7 +298,7 @@ void FDdmaSetChanSelection(uintptr base_addr, u32 chan, u32 slave_id) reg_val |= FDDMA_CHAN_4_7_SEL(chan, slave_id); reg_val |= FDDMA_CHAN_4_7_SEL_EN(chan); FDdmaWriteReg(base_addr, FDDMA_CHAN_4_7_CFG_OFFSET, reg_val); - FDDMA_DEBUG("ddma@%p set chan-%d slave id-%d, 0x%x", base_addr, chan, slave_id, FDdmaReadReg(base_addr, FDDMA_CHAN_4_7_CFG_OFFSET)); + FDDMA_DEBUG("ddma%p sets the slaveid of chan-%d to %d, 0x%x", base_addr, chan, slave_id, FDdmaReadReg(base_addr, FDDMA_CHAN_4_7_CFG_OFFSET)); } return; @@ -310,13 +314,17 @@ void FDdmaSetChanSelection(uintptr base_addr, u32 chan, u32 slave_id) */ void FDdmaSetChanBind(uintptr base_addr, u32 chan, boolean bind) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_BIND_OFFSET); if (bind) + { reg_val |= BIT(chan); + } else + { reg_val &= ~BIT(chan); + } FDDMA_DEBUG("ddma@%p %s chan-%d, 0x%x", base_addr, bind ? "bind" : "unbind", chan, FDdmaReadReg(base_addr, FDDMA_CHAN_BIND_OFFSET)); FDdmaWriteReg(base_addr, FDDMA_CHAN_BIND_OFFSET, reg_val); @@ -333,12 +341,16 @@ void FDdmaSetChanBind(uintptr base_addr, u32 chan, boolean bind) */ void FDdmaSetChanDirection(uintptr base_addr, u32 chan, boolean is_rx) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan)); if (is_rx) - reg_val |= FDDMA_CHAN_CTL_RX_MODE; /* device to memory */ + { + reg_val |= FDDMA_CHAN_CTL_RX_MODE; /* device to memory */ + } else - reg_val &= ~FDDMA_CHAN_CTL_RX_MODE; /* memory to device */ + { + reg_val &= ~FDDMA_CHAN_CTL_RX_MODE; /* memory to device */ + } FDdmaWriteReg(base_addr, FDDMA_CHAN_CTL_OFFSET(chan), reg_val); return; } @@ -353,7 +365,7 @@ void FDdmaSetChanDirection(uintptr base_addr, u32 chan, boolean is_rx) */ void FDdmaSetChanTimeout(uintptr base_addr, u32 chan, u32 timeout) { - FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "chan %d not support", chan); + FASSERT_MSG((FDDMA_NUM_OF_CHAN > chan), "Channel %d is not supported", chan); u32 reg_val = FDdmaReadReg(base_addr, FDDMA_CHAN_TIMEOUT_CNT_OFFSET(chan)); if (0 < timeout) diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.h b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.h index 2334abd184..e84e6c6fd9 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_hw.h @@ -19,16 +19,12 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ -#ifndef DRIVERS_FDDMA_HW_H -#define DRIVERS_FDDMA_HW_H +#ifndef FDDMA_HW_H +#define FDDMA_HW_H -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "fassert.h" @@ -36,6 +32,12 @@ extern "C" #include "fio.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + /************************** Constant Definitions *****************************/ /** @name Register Map * diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_intr.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_intr.c index c71ba37018..76cfdecb80 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_intr.c @@ -14,12 +14,12 @@ * FilePath: fddma_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for ddma interrupt implementation + * Description:  This file is for ddma interrupt implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ @@ -112,7 +112,9 @@ void FDdmaIrqHandler(s32 vector, void *args) for (chan = FDDMA_CHAN_0; chan < FDDMA_NUM_OF_CHAN; chan++) { if (0 == (FDDMA_STA_CHAN_REQ_DONE(chan) & status)) + { continue; + } FDDMA_INFO("handle chan %d", chan); FDdmaClearChanIrq(base_addr, chan); /* clear interrupt status */ diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_selftest.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_selftest.c index dfe9dea6a5..5f1bd6557e 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_selftest.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_selftest.c @@ -14,12 +14,12 @@ * FilePath: fddma_selftest.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for ddma self test + * Description:  This file is for ddma self test * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_sinit.c b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_sinit.c index 0a7ad7f430..ac5bdd5be1 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fddma/fddma_sinit.c @@ -14,12 +14,12 @@ * FilePath: fddma_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for static initialization + * Description:  This file is for static initialization * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/5/13 init commit + * 1.0 zhugengyu 2022/5/13 init commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.c b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.c index f43a56bd27..e5d256db21 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.c @@ -14,13 +14,13 @@ * FilePath: fgdma.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for + * Description:  This file is for gdma user function implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 support chan alloc. and qos setting + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 support chan alloc. and qos setting */ @@ -65,15 +65,17 @@ FError FGdmaCfgInitialize(FGdma *const instance_p, const FGdmaConfig *input_conf if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FGDMA_WARN("device is already initialized!!!"); + FGDMA_WARN("The device has been initialized!!"); } FGdmaDeInitialize(instance_p); if (&instance_p->config != input_config) + { instance_p->config = *input_config; + } - FASSERT_MSG((0 != base_addr), "invalid device base address"); + FASSERT_MSG((0 != base_addr), "Invalid device base address"); FGdmaReset(instance_p); if (FGDMA_SUCCESS == ret) @@ -95,11 +97,11 @@ void FGdmaDeInitialize(FGdma *const instance_p) FASSERT(instance_p); u32 chan; - for (chan = FGDMA_CHAN0_INDEX; chan < FGDMA_NUM_OF_CHAN; chan++) + for (chan = 0; chan < FGDMA_NUM_OF_CHAN; chan++) { if (NULL != instance_p->chans[chan]) { - FGDMA_WARN("chan-%d might be in use !!!", chan); + FGDMA_WARN("chans-% d may be used!!!", chan); } } @@ -166,18 +168,26 @@ FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const dma_chan, if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } + if(chan_idx >= FGDMA_NUM_OF_CHAN) + { + FGDMA_ERROR("Channel %d is in use !!!", chan_idx); + return FGDMA_ERR_CHAN_IN_USE; + } + if (NULL != instance_p->chans[chan_idx]) { - FGDMA_ERROR("chan %d is in use !!!", chan_idx); + FGDMA_ERROR("Channel %d is in use !!!", chan_idx); return FGDMA_ERR_CHAN_IN_USE; } if (&dma_chan->config != dma_chan_config) + { dma_chan->config = *dma_chan_config; + } /* disable and reset chan */ FGdmaChanDisable(base_addr, chan_idx); @@ -190,7 +200,7 @@ FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const dma_chan, reg_val = FGDMA_READREG(base_addr, FGDMA_CHX_MODE_OFFSET(chan_idx)); if (FGDMA_OPER_BDL == dma_chan->config.trans_mode) { - FGDMA_INFO("set as BDL mode"); + FGDMA_INFO("Set to BDL mode"); reg_val |= FGDMA_CHX_MODE_BDL_EN; if (dma_chan->config.roll_back) @@ -204,7 +214,7 @@ FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const dma_chan, } else { - FGDMA_INFO("set as Direct mode"); + FGDMA_INFO("Set to Direct mode"); reg_val &= ~FGDMA_CHX_MODE_BDL_EN; reg_val &= ~FGDMA_CHX_MODE_BDL_ROLL_EN; } @@ -249,7 +259,7 @@ FError FGdmaDellocateChan(FGdmaChan *const dma_chan) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } @@ -291,12 +301,12 @@ FError FGdmaDirectTransfer(FGdmaChan *const chan_p, uintptr src_addr, uintptr ds if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } if ((src_addr % FGDMA_GET_BURST_SIZE(chan_p->config.rd_align)) || - (dst_addr % FGDMA_GET_BURST_SIZE(chan_p->config.wr_align))) + (dst_addr % FGDMA_GET_BURST_SIZE(chan_p->config.wr_align))) { FGDMA_ERROR("src addr 0x%x or dst addr 0x%x not aligned with %d bytes", src_addr, dst_addr, FGDMA_ADDR_ALIGMENT); @@ -365,27 +375,27 @@ FError FGdmaDirectTransfer(FGdmaChan *const chan_p, uintptr src_addr, uintptr ds FError FGdmaAppendBDLEntry(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len) { FASSERT(chan_p); - FASSERT_MSG((chan_p->config.descs) && (chan_p->config.total_desc_num > 0), "BDL descriptor list not yet assign !!!"); + FASSERT_MSG((chan_p->config.descs) && (chan_p->config.total_desc_num > 0), "The list of BDL descriptors has not yet been assigned !!!"); u32 desc_idx = chan_p->config.valid_desc_num; FGdmaBdlDesc *desc_entry = &(chan_p->config.descs[desc_idx]); if (chan_p->config.valid_desc_num >= chan_p->config.total_desc_num) { - FGDMA_ERROR("total BDL descriptor num is %d, already used up", chan_p->config.total_desc_num); + FGDMA_ERROR("The total BDL descriptor num is %d and has been used up", chan_p->config.total_desc_num); return FGDMA_ERR_BDL_NOT_ENOUGH; } if ((0U != (dst_addr % FGDMA_GET_BURST_SIZE(chan_p->config.wr_align))) || - (0U != (src_addr % FGDMA_GET_BURST_SIZE(chan_p->config.rd_align)))) + (0U != (src_addr % FGDMA_GET_BURST_SIZE(chan_p->config.rd_align)))) { - FGDMA_ERROR("src addr 0x%x or dst addr 0x%x not aligned with %d bytes", + FGDMA_ERROR("SRC addr 0x%x or DST addr 0x%x are not aligned with the %d transfer size", src_addr, dst_addr, FGDMA_GET_BURST_SIZE(chan_p->config.wr_align)); return FGDMA_ERR_INVALID_ADDR; } if (0U != (data_len % chan_p->config.wr_align)) { - FGDMA_ERROR("data length %d must be N times of burst size %d !!!", + FGDMA_ERROR("The data length %d must be N times the burst size %d !!!", data_len, chan_p->config.wr_align); return FGDMA_ERR_INVALID_SIZE; } @@ -438,13 +448,13 @@ FError FGdmaBDLTransfer(FGdmaChan *const chan_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } if (0 == chan_p->config.valid_desc_num) { - FGDMA_WARN("need to assign BDL entry fisrt !!!"); + FGDMA_WARN("First, the BDL entries need to be allocated !!!"); return FGDMA_SUCCESS; } @@ -499,13 +509,16 @@ FError FGdmaStart(FGdma *const instance_p) FASSERT(instance_p); uintptr base_addr = instance_p->config.base_addr; u32 reg_val; - + if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } - + if(FGDMA_TRANS_NEED_RESET_MASK & instance_p->config.caps) + { + FGdmaSoftwareReset(base_addr); + } FGdmaIrqEnable(base_addr); reg_val = FGDMA_READREG(base_addr, FGDMA_CTL_OFFSET); @@ -513,6 +526,8 @@ FError FGdmaStart(FGdma *const instance_p) reg_val |= FGDMA_CTL_OT_SET(FGDMA_OUTSTANDING); /* 设置传输outstanding数 */ reg_val |= FGDMA_CTL_ENABLE; /* 使能DMA传输 */ FGDMA_WRITEREG(base_addr, FGDMA_CTL_OFFSET, reg_val); + + return FGDMA_SUCCESS; // 放到初始化 } @@ -533,20 +548,22 @@ FError FGdmaStop(FGdma *const instance_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGDMA_ERROR("dma instance not init !!!"); + FGDMA_ERROR("The dma instance is not initialized !!!"); return FGDMA_ERR_NOT_INIT; } /* Abort 流程 */ - for (chan_id = FGDMA_CHAN0_INDEX; chan_id < FGDMA_NUM_OF_CHAN; chan_id++) + for (chan_id = 0; chan_id < FGDMA_NUM_OF_CHAN; chan_id++) { if (NULL == instance_p->chans[chan_id]) - continue; /* skip un-allocate channel */ + { + continue; /* skip un-allocate channel */ + } chan_status = FGdmaReadChanStatus(base_addr, chan_id); if (FGDMA_CHX_INT_STATE_BUSY & chan_status) { - FGDMA_WARN("chan-%d has abort unfinished request !!!", chan_id); + FGDMA_WARN("chan-%d was forcibly closed !!!", chan_id); FGdmaChanDisable(base_addr, chan_id); /* 关闭通道 */ FGdmaChanReset(base_addr, chan_id); /* 需要进行软复位,否则再次使能通道时,仍然会执行之前的请求 */ } @@ -559,7 +576,7 @@ FError FGdmaStop(FGdma *const instance_p) } FGdmaDisable(base_addr); - + return FGDMA_SUCCESS; } @@ -631,22 +648,22 @@ static void FGdmaReset(FGdma *const instance_p) u32 chan; u32 reg_val; - FGDMA_INFO("reset ctrl @0x%x ...", base_addr); + FGDMA_INFO("Controller base address is %p ...", base_addr); FGdmaDisable(base_addr); FGdmaSoftwareReset(base_addr); FGdmaSetQos(instance_p); - FGDMA_INFO("reset chan ..."); + FGDMA_INFO("Reset channel"); - for (chan = FGDMA_CHAN0_INDEX; chan < FGDMA_NUM_OF_CHAN; chan++) + for (chan = 0; chan < FGDMA_NUM_OF_CHAN; chan++) { FGdmaChanDisable(base_addr, chan); FGdmaChanIrqDisable(base_addr, chan); FGdmaChanReset(base_addr, chan); FGdmaSetChanClock(base_addr, chan, FALSE); } - + return; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.h b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.h index 0319af3618..8474ba8882 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.h +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.h @@ -14,17 +14,22 @@ * FilePath: fgdma.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:35 - * Description:  This files is for gdma user api implementation + * Description:  This file is for gdma user api implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ -#ifndef DRIVERS_FGDMA_H -#define DRIVERS_FGDMA_H +#ifndef FGDMA_H +#define FGDMA_H + +#include "ftypes.h" +#include "fassert.h" +#include "ferror_code.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" @@ -33,33 +38,15 @@ extern "C" /***************************** Include Files *********************************/ -#include "ftypes.h" -#include "fassert.h" -#include "ferror_code.h" -#include "fkernel.h" + /************************** Constant Definitions *****************************/ -typedef enum -{ - FGDMA_CHAN0_INDEX = 0, - FGDMA_CHAN1_INDEX = 1, - FGDMA_CHAN2_INDEX = 2, - FGDMA_CHAN3_INDEX = 3, - FGDMA_CHAN4_INDEX = 4, - FGDMA_CHAN5_INDEX = 5, - FGDMA_CHAN6_INDEX = 6, - FGDMA_CHAN7_INDEX = 7, - FGDMA_CHAN8_INDEX = 8, - FGDMA_CHAN9_INDEX = 9, - FGDMA_CHAN10_INDEX = 10, - FGDMA_CHAN11_INDEX = 11, - FGDMA_CHAN12_INDEX = 12, - FGDMA_CHAN13_INDEX = 13, - FGDMA_CHAN14_INDEX = 14, - FGDMA_CHAN15_INDEX = 15, - FGDMA_NUM_OF_CHAN -} FGdmaChanIndex; /* 16个独立通道, 0 ~ 15 */ +/* gdma capacity mask */ + +#define FGDMA_IRQ1_MASK BIT(0) /* All Gdma channel share a single interrupt */ +#define FGDMA_IRQ2_MASK BIT(1) /* Each gdma channel owns an independent interrupt */ +#define FGDMA_TRANS_NEED_RESET_MASK BIT(2) /* Gdma needs to be reset before transmission */ typedef enum { @@ -127,11 +114,12 @@ typedef struct _FGdmaChan FGdmaChan; typedef struct { u32 instance_id; /* GDMA控制器ID */ - u32 irq_num; /* GDMA控制器中断号 */ + u32 irq_num[FGDMA_NUM_OF_CHAN]; /* GDMA控制器中断号 */ u32 irq_prority; /* GDMA控制器中断优先级 */ volatile uintptr_t base_addr; /* GDMA控制器基地址 */ FGdmaOperPriority rd_qos; /* 读操作优先级 */ FGdmaOperPriority wr_qos; /* 写操作优先级 */ + u32 caps; /* driver capacity */ } FGdmaConfig; /* GDMA控制器配置 */ typedef struct @@ -154,6 +142,8 @@ typedef struct FASSERT_STATIC(0x20U == sizeof(FGdmaBdlDesc)); +typedef u32 FGdmaChanIndex; + typedef struct { FGdmaChanIndex chan_id; /* DMA通道ID */ @@ -172,10 +162,11 @@ typedef struct typedef void (*FGdmaChanEvtHandler)(FGdmaChan *const chan, void *args); + typedef struct _FGdmaChan { FGdmaChanConfig config; /* DMA通道配置 */ - FGdma *gdma; /* DMA控制器实例 */ + FGdma *gdma; /* DMA控制器实例 */ FGdmaChanEvtHandler evt_handlers[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数 */ void *evt_handler_args[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数入参 */ } FGdmaChan; /* GDMA通道实例 */ @@ -192,29 +183,29 @@ typedef struct _FGdma /***************** Macros (Inline Functions) Definitions *********************/ /* 获取默认的通道配置 */ #define FGDMA_DEFAULT_DIRECT_CHAN_CONFIG(_chan_id)\ -(FGdmaChanConfig){ \ - .chan_id = (_chan_id),\ - .rd_align = FGDMA_BURST_SIZE_4_BYTE,\ - .wr_align = FGDMA_BURST_SIZE_4_BYTE,\ - .rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ - .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ - .trans_mode = FGDMA_OPER_DIRECT,\ - .roll_back = FALSE\ -} + (FGdmaChanConfig){ \ + .chan_id = (_chan_id),\ + .rd_align = FGDMA_BURST_SIZE_4_BYTE,\ + .wr_align = FGDMA_BURST_SIZE_4_BYTE,\ + .rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ + .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ + .trans_mode = FGDMA_OPER_DIRECT,\ + .roll_back = FALSE\ + } #define FGDMA_DEFAULT_BDL_CHAN_CONFIG(_chan_id, _bdl_descs, _bdl_desc_num)\ -(FGdmaChanConfig){ \ - .chan_id = (_chan_id),\ - .rd_align = FGDMA_BURST_SIZE_4_BYTE,\ - .wr_align = FGDMA_BURST_SIZE_4_BYTE,\ - .rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ - .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ - .trans_mode = FGDMA_OPER_BDL,\ - .roll_back = FALSE,\ - .descs = _bdl_descs,\ - .total_desc_num = _bdl_desc_num,\ - .valid_desc_num = 0U\ -} + (FGdmaChanConfig){ \ + .chan_id = (_chan_id),\ + .rd_align = FGDMA_BURST_SIZE_4_BYTE,\ + .wr_align = FGDMA_BURST_SIZE_4_BYTE,\ + .rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ + .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\ + .trans_mode = FGDMA_OPER_BDL,\ + .roll_back = FALSE,\ + .descs = _bdl_descs,\ + .total_desc_num = _bdl_desc_num,\ + .valid_desc_num = 0U\ + } /************************** Function Prototypes ******************************/ /* 获取GDMA控制器默认配置 */ @@ -250,6 +241,7 @@ FError FGdmaStop(FGdma *const instance_p); /* GDMA中断处理函数 */ void FGdmaIrqHandler(s32 vector, void *args); +void FGdmaIrqHandlerPrivateChannel(s32 vector, void *args); /* 注册GDMA通道事件回调函数 */ void FGdmaChanRegisterEvtHandler(FGdmaChan *const chan_p, FGdmaChanEvtType evt, diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_g.c b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_g.c index 8cb1ba77f8..fcd0dbc7f1 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_g.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_g.c @@ -14,13 +14,13 @@ * FilePath: fgdma_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:09 - * Description:  This files is for static variables definition + * Description:  This file is for static variables definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ /***************************** Include Files *********************************/ @@ -47,10 +47,31 @@ const FGdmaConfig fgdma_cfg_tbl[FGDMA_INSTANCE_NUM] = { .instance_id = FGDMA0_ID, .base_addr = FGDMA0_BASE_ADDR, - .irq_num = FGDMA0_IRQ_NUM, + .irq_num ={ + FGDMA0_CHANNEL0_IRQ_NUM, + #if defined(FGDMA0_CHANNEL1_IRQ_NUM) + FGDMA0_CHANNEL1_IRQ_NUM, + #endif + #if defined(FGDMA0_CHANNEL2_IRQ_NUM) + FGDMA0_CHANNEL2_IRQ_NUM, + #endif + #if defined(FGDMA0_CHANNEL3_IRQ_NUM) + FGDMA0_CHANNEL3_IRQ_NUM, + #endif + #if defined(FGDMA0_CHANNEL4_IRQ_NUM) + FGDMA0_CHANNEL4_IRQ_NUM, + #endif + #if defined(FGDMA0_CHANNEL5_IRQ_NUM) + FGDMA0_CHANNEL5_IRQ_NUM, + #endif + #if defined(FGDMA0_CHANNEL6_IRQ_NUM) + FGDMA0_CHANNEL6_IRQ_NUM, + #endif + } , .irq_prority = 0, .rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL, - .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL + .wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL, + .caps = FGDMA0_CAPACITY } }; diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_hw.h b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_hw.h index 14e45c451e..6ab2ffc9fa 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_hw.h @@ -14,17 +14,21 @@ * FilePath: fgdma_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for + * Description:  This file is for gdma register related defintion * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ -#ifndef DRIVERS_FGDMA_HW_H -#define DRIVERS_FGDMA_HW_H +#ifndef FGDMA_HW_H +#define FGDMA_HW_H + +#include "fparameters.h" +#include "fio.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" @@ -32,10 +36,6 @@ extern "C" #endif /***************************** Include Files *********************************/ -#include "fparameters.h" -#include "fio.h" -#include "fkernel.h" - /************************** Constant Definitions *****************************/ /** @name Register Map @@ -429,9 +429,13 @@ static inline void FGdmaSetChanClock(uintptr base_addr, u32 chan, boolean enable { u32 reg_val = FGDMA_READREG(base_addr, FGDMA_LP_OFFSET); if (enable) - reg_val &= ~FGDMA_CHX_LP_CTL(chan); /* 写0开启通道时钟 */ + { + reg_val &= ~FGDMA_CHX_LP_CTL(chan); /* 写0开启通道时钟 */ + } else - reg_val |= FGDMA_CHX_LP_CTL(chan); /* 写1关断通道时钟 */ + { + reg_val |= FGDMA_CHX_LP_CTL(chan); /* 写1关断通道时钟 */ + } FGDMA_WRITEREG(base_addr, FGDMA_LP_OFFSET, reg_val); return; diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_intr.c b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_intr.c index 80ba4ea4d4..a00ac2d51f 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_intr.c @@ -14,13 +14,13 @@ * FilePath: fgdma_intr.c * Date: 2022-05-16 17:01:48 * LastEditTime: 2022-05-16 17:01:49 - * Description:  This files is for interrupt api implmentation + * Description:  This file is for interrupt api implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ /***************************** Include Files *********************************/ @@ -103,7 +103,7 @@ static void FGdmaChanIrqHandler(FGdmaChan *const chan_p) /** * @name: FGdmaIrqHandler - * @msg: GDMA中断处理函数 + * @msg: 当instance_p->config.caps 具有FGDMA_IRQ1_MASK特性时,此函数作为GDMA中断处理函数 * @return {void} 无 * @param {s32} vector, 中断号 * @param {void} *args, 中断参数 @@ -113,6 +113,7 @@ void FGdmaIrqHandler(s32 vector, void *args) FASSERT(args); FGdma *const instance_p = (FGdma * const)args; FASSERT(FT_COMPONENT_IS_READY == instance_p->is_ready); + FASSERT(FGDMA_IRQ1_MASK & instance_p->config.caps); uintptr base_addr = instance_p->config.base_addr; u32 chan_id; @@ -120,20 +121,58 @@ void FGdmaIrqHandler(s32 vector, void *args) FGDMA_INFO("status: 0x%x", status); FGdmaIrqDisable(base_addr); - for (chan_id = FGDMA_CHAN0_INDEX; chan_id < FGDMA_NUM_OF_CHAN; chan_id++) + for (chan_id = 0; chan_id < FGDMA_NUM_OF_CHAN; chan_id++) { - if (!(FGDMA_CHX_INTR_STATE(chan_id) & status)) + if (!(FGDMA_CHX_INTR_STATE(chan_id) & status)) + { continue; + } /* channel interrupt happens */ FASSERT_MSG((NULL != instance_p->chans[chan_id]), "invalid chan interrupt event !!!"); FGdmaChanIrqHandler(instance_p->chans[chan_id]); } FGdmaIrqEnable(base_addr); - + status = FGdmaReadStatus(base_addr); + FGDMA_INFO("after status: 0x%x", status); return; } +/** + * @name: FGdmaIrqHandlerPrivateChannel + * @msg: 当instance_p->config.caps 具有FGDMA_IRQ2_MASK特性时,此函数作为GDMA中断处理函数 + * @return {void} 无 + * @param {s32} vector, 中断号 + * @param {void} *args, 中断参数 + */ +void FGdmaIrqHandlerPrivateChannel(s32 vector, void *args) +{ + FASSERT(args); + FGdmaChan *gdma_chan = (FGdmaChan *)args; + FASSERT(gdma_chan); + FGdma *const instance_p = (FGdma *const)gdma_chan->gdma; + FASSERT(FT_COMPONENT_IS_READY == instance_p->is_ready); + FASSERT(FGDMA_IRQ2_MASK & instance_p->config.caps); + uintptr base_addr = instance_p->config.base_addr; + u32 chan_id; + FGDMA_INFO("FGdmaIrqHandlerPrivateChannel is here %d \r\n",vector); + chan_id = gdma_chan->config.chan_id ; + FASSERT(chan_id <= FGDMA_NUM_OF_CHAN); + u32 status = FGdmaReadStatus(base_addr); + FGDMA_INFO("status: 0x%x", status); + if(!(FGDMA_CHX_INTR_STATE(chan_id) & status)) + { + FGDMA_WARN("The interrupt state does not match the interrupt chan_id ,chan_id is %d, interrupt state is 0x%x ",chan_id,status); + } + + FASSERT_MSG((NULL != instance_p->chans[chan_id]), "invalid chan interrupt event !!!"); + FGdmaChanIrqHandler(instance_p->chans[chan_id]); + status = FGdmaReadStatus(base_addr); + FGDMA_INFO("after status: 0x%x", status); + return; +} + + /** * @name: FGdmaChanRegisterEvtHandler * @msg: 注册GDMA通道事件回调函数 diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_selftest.c b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_selftest.c index fe16b3e525..31267c12dd 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_selftest.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_selftest.c @@ -14,13 +14,13 @@ * FilePath: fgdma_selftest.c * Date: 2022-05-20 13:39:27 * LastEditTime: 2022-05-20 13:39:27 - * Description:  This files is for self test implementation + * Description:  This file is for self test implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ /***************************** Include Files *********************************/ #include @@ -60,7 +60,7 @@ void FGdmaDumpRegisterVals(uintptr base_addr, u32 max_chan) FGDMA_DEBUG("lp[0x%x] : 0x%x", FGDMA_LP_OFFSET, FGDMA_READREG(base_addr, FGDMA_LP_OFFSET)); FGDMA_DEBUG("qos[0x%x] : 0x%x", FGDMA_QOS_CFG_OFFSET, FGDMA_READREG(base_addr, FGDMA_QOS_CFG_OFFSET)); - for (u32 chan = FGDMA_CHAN0_INDEX; chan <= max_chan; chan++) + for (u32 chan = 0; chan <= max_chan; chan++) { FGDMA_DEBUG("chan-%d", chan); FGDMA_DEBUG(" ctrl[0x%x]: 0x%x", FGDMA_CHX_CTL_OFFSET(chan), FGDMA_READREG(base_addr, FGDMA_CHX_CTL_OFFSET(chan))); diff --git a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_sinit.c b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_sinit.c index bb315ae0c0..96be6e2a1b 100644 --- a/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma_sinit.c @@ -14,13 +14,13 @@ * FilePath: fgdma_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:15 - * Description:  This files is for gdma static init + * Description:  This file is for gdma static init * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 huanghe 2021-11-5 init commit - * 1.1 zhugengyu 2022-5-16 modify according to tech manual. + * 1.0 huanghe 2021/11/5 init commit + * 1.1 zhugengyu 2022/5/16 modify according to tech manual. */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/Kconfig b/bsp/phytium/libraries/standalone/drivers/eth/Kconfig index c9531733fe..f041d27764 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/eth/Kconfig @@ -4,11 +4,11 @@ menu "Eth Configuration" bool prompt "Use FXMAC" default n - + config ENABLE_FGMAC bool prompt "Use FGMAC" - default n + default n if ENABLE_FGMAC source "$STANDALONE_DIR/drivers/eth/fgmac/Kconfig" @@ -17,6 +17,6 @@ menu "Eth Configuration" if ENABLE_FXMAC source "$STANDALONE_DIR/drivers/eth/fxmac/Kconfig" endif - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.c index bef00ec931..94e15135fa 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.c @@ -14,17 +14,18 @@ * FilePath: fgmac.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for gmac driver .Functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ /***************************** Include Files *********************************/ #include - #include "fio.h" #include "ferror_code.h" #include "ftypes.h" @@ -106,35 +107,35 @@ FError FGmacCfgInitialize(FGmac *instance_p, const FGmacConfig *input_config_p) /* indicating device is started */ if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FGMAC_WARN("device is already initialized!!!"); + FGMAC_WARN("Device is already initialized!!!"); } /* de-initialize device instance */ FGmacDeInitialize(instance_p); instance_p->config = *input_config_p; - - /*Phy Awaken*/ - + /* Phy Awaken */ ret = FGmacPhyAwaken(instance_p); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("phy awaken failed!"); + FGMAC_ERROR("Phy awaken failed!"); return ret; } /* initialize the gmac controller */ - ret = FGmacReset(instance_p); // permmit failed + ret = FGmacReset(instance_p); if (FGMAC_SUCCESS != ret) { - printf("FGmacReset failed \r\n"); + /*permit failed*/ + FGMAC_ERROR("Gmac reset failed."); } - ret = FGmacControllerConfigure(instance_p); if (FGMAC_SUCCESS != ret) + { return ret; + } /* initialize the gmac dma controller */ ret = FGmacDmaConfigure(instance_p); @@ -200,7 +201,7 @@ static FError FGmacReset(FGmac *instance_p) /* recover mac address after softwate reset */ FGmacSetMacAddr(base_addr, mac_addr); - return ret;// may return error + return ret; } /** @@ -261,9 +262,13 @@ void FGmacControllerDuplexConfig(FGmac *instance_p, u32 duplex) /* 设置双工模式 */ if (duplex == FGMAC_PHY_MODE_FULLDUPLEX) + { reg_val |= FGMAC_CONF_DUPLEX_MODE; + } else + { reg_val &= ~FGMAC_CONF_DUPLEX_MODE; + } FGMAC_WRITE_REG32(base_addr, FGMAC_CONF_OFFSET, reg_val); @@ -313,15 +318,23 @@ static FError FGmacControllerConfigure(FGmac *instance_p) /* 双工模式 */ if (instance_p->config.duplex_mode) + { reg_val |= FGMAC_CONF_DUPLEX_MODE; + } else + { reg_val &= ~FGMAC_CONF_DUPLEX_MODE; + } /* 使能校验和卸载IPS */ if (FGMAC_CHECKSUM_BY_HARDWARE == instance_p->config.cheksum_mode) + { reg_val |= FGMAC_CONF_IPC; + } else + { reg_val &= ~FGMAC_CONF_IPC; + } /* 重发DR=1, 重发一次 */ reg_val |= FGMAC_CONF_DISABLE_RETRY; @@ -486,7 +499,7 @@ static FError FGmacDmaConfigure(FGmac *instance_p) if (FGMAC_SUCCESS != ret) { - printf("FGmac Flush Failed\r\n"); + FGMAC_ERROR("Gmac flush failed."); } /* AXI 突发长度 BLEN 16,8,4 */ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.h b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.h index e4dc25d5fc..03e5fbace1 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac.h @@ -14,16 +14,22 @@ * FilePath: fgmac.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for gmac driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ -#ifndef DRIVERS_ETH_FGMAC_H -#define DRIVERS_ETH_FGMAC_H +#ifndef FGMAC_H +#define FGMAC_H + +#include "ftypes.h" +#include "fassert.h" +#include "ferror_code.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" @@ -32,11 +38,6 @@ extern "C" /***************************** Include Files *********************************/ -#include "ftypes.h" -#include "fassert.h" -#include "ferror_code.h" -#include "fkernel.h" - #define FGMAC_PHY_MAX_NUM 32U /************************** Constant Definitions *****************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_dma.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_dma.c index 019c4f659a..e7dc4a6602 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_dma.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_dma.c @@ -14,11 +14,12 @@ * FilePath: fgmac_dma.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file implements dma descriptor ring related functions. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/06/04 first release */ /***************************** Include Files *********************************/ @@ -77,7 +78,7 @@ FError FGmacSetupRxDescRing(FGmac *instance_p, volatile FGmacDmaDesc *rx_desc_tb if TRUE, return error because DMA register can only hold 32 bit memory address */ if ((FGMAC_DMA_IS_64_BIT_MEMORY(desc_end)) || (FGMAC_DMA_IS_64_BIT_MEMORY(buf_end))) { - FGMAC_ERROR("invalid rx descriptor memory %p or rx dma buf memory %p", + FGMAC_ERROR("Invalid rx descriptor memory %p or rx dma buf memory %p", desc_end, buf_end); return FGMAC_ERR_INVALID_DMA_MEM; } @@ -140,7 +141,7 @@ FError FGmacSetupTxDescRing(FGmac *instance_p, volatile FGmacDmaDesc *tx_desc_tb if TRUE, return error because DMA register can only hold 32 bit memory address */ if ((FGMAC_DMA_IS_64_BIT_MEMORY(desc_end)) || (FGMAC_DMA_IS_64_BIT_MEMORY(buf_end))) { - FGMAC_ERROR("invalid rx descriptor memory %p or rx dma buf memory %p", + FGMAC_ERROR("Invalid rx descriptor memory %p or rx dma buf memory %p", desc_end, buf_end); return FGMAC_ERR_INVALID_DMA_MEM; } @@ -183,7 +184,7 @@ FError FGmacStartTrans(FGmac *instance_p) FASSERT(instance_p); if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGMAC_ERROR("device is already initialized!!!"); + FGMAC_ERROR("Device is already initialized!!!"); return FGMAC_ERR_NOT_READY; } @@ -203,7 +204,7 @@ FError FGmacStopTrans(FGmac *instance_p) FASSERT(instance_p); if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FGMAC_ERROR("device is already initialized!!!"); + FGMAC_ERROR("Device is already initialized!!!"); return FGMAC_ERR_NOT_READY; } @@ -227,7 +228,7 @@ FError FGmacRecvFrame(FGmac *instance_p) u32 flag = (FGMAC_DMA_RDES0_FIRST_DESCRIPTOR | FGMAC_DMA_RDES0_LAST_DESCRIPTOR); while ((0 == (FGMAC_DMA_RDES0_OWN & cur_rx_desc->status)) && - (desc_cnt < rx_ring->desc_max_num)) + (desc_cnt < rx_ring->desc_max_num)) { desc_cnt++; @@ -281,7 +282,9 @@ FError FGmacSendFrame(FGmac *instance_p, u32 frame_len) { buf_cnt = frame_len / max_packet_size; if (frame_len % max_packet_size) + { buf_cnt++; + } } else { diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_g.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_g.c index a72ab1b34b..ef6eb7ce02 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_g.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_g.c @@ -14,11 +14,13 @@ * FilePath: fgmac_g.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for configuration table that specifies the configuration of + * ethernet devices . * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ /* - This file contains a configuration table that specifies the configuration @@ -28,29 +30,32 @@ #include "fparameters.h" #include "fgmac.h" +#include "fgmac_phy.h" /************************** Constant Definitions *****************************/ -const FGmacConfig FGMAC_CONFIG_TBL[GMAC_INSTANCE_NUM] = +const FGmacConfig FGMAC_CONFIG_TBL[FGMAC_NUM] = { - [GMAC_INSTANCE_0] = + [FGMAC0_ID] = { - .instance_id = GMAC_INSTANCE_0, - .base_addr = GMAC_INSTANCE_0_BASE_ADDR, - .irq_num = GMAC_INSTANC_0_IRQ, + .instance_id = FGMAC0_ID, + .base_addr = FGMAC0_BASE_ADDR, + .irq_num = FGMAC0_IRQ_NUM, .irq_prority = 0, .cheksum_mode = FGMAC_CHECKSUM_BY_SOFTWARE, - .max_packet_size = GMAC_MAX_PACKET_SIZE + .max_packet_size = FGMAC_MAX_PACKET_SIZE, + .mdc_clk_hz = FGMAC_PHY_MII_ADDR_CR_250_300MHZ, }, - [GMAC_INSTANCE_1] = + [FGMAC1_ID] = { - .instance_id = GMAC_INSTANCE_1, - .base_addr = GMAC_INSTANCE_1_BASE_ADDR, - .irq_num = GMAC_INSTANC_1_IRQ, + .instance_id = FGMAC1_ID, + .base_addr = FGMAC1_BASE_ADDR, + .irq_num = FGMAC1_IRQ_NUM, .irq_prority = 0, .cheksum_mode = FGMAC_CHECKSUM_BY_SOFTWARE, - .max_packet_size = GMAC_MAX_PACKET_SIZE + .max_packet_size = FGMAC_MAX_PACKET_SIZE, + .mdc_clk_hz = FGMAC_PHY_MII_ADDR_CR_250_300MHZ, } }; diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.c index b4a493a2dd..b354f143b5 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.c @@ -14,20 +14,19 @@ * FilePath: fgmac_hw.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for manipulation of hardware registers . * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ #include "fassert.h" #include "fdebug.h" - #include "fgmac.h" #include "fgmac_hw.h" - /***************************** Include Files *********************************/ /************************** Constant Definitions *****************************/ @@ -110,7 +109,7 @@ FError FGmacSoftwareReset(uintptr base_addr, int timeout) if ((0 >= timeout) && (reg_val & FGMAC_DMA_BUS_SWR)) { - FGMAC_ERROR("reset timeout, please check phy connection!!!"); + FGMAC_ERROR("Reset timeout, please check phy connection!!!"); return FGMAC_ERR_TIMEOUT; } @@ -131,7 +130,7 @@ FError FGmacFlushTxFifo(uintptr base_addr, int timeout) if ((0 >= timeout) && (reg_val & FGMAC_DMA_OP_FTF)) { - FGMAC_ERROR("flush tx fifo timeout !!!"); + FGMAC_ERROR("Flush tx fifo timeout !!!"); return FGMAC_ERR_TIMEOUT; } @@ -158,7 +157,7 @@ FError FGmacPhyWaitBusBusy(uintptr base_addr, int timeout) if (0 >= timeout) { - FGMAC_ERROR("timeout when wait GMII timeout"); + FGMAC_ERROR("Wait gmii timeout"); return FGMAC_ERR_TIMEOUT; } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.h b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.h index d192d81f4c..cd7ba1754f 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_hw.h @@ -14,16 +14,16 @@ * FilePath: fgmac_hw.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for manipulation of hardware registers . * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ -#ifndef DRIVERS_ETH_FGMAC_HW_H -#define DRIVERS_ETH_FGMAC_HW_H - +#ifndef FGMAC_HW_H +#define FGMAC_HW_H /* - 传入模块基地址,不能复杂结构体 - hardware interface of device || low-level driver function prototypes @@ -37,16 +37,16 @@ note: 本文件不能引用fooxx.h */ -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "fkernel.h" #include "fio.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif /************************** Constant Definitions *****************************/ /** @name Register Map @@ -269,7 +269,7 @@ extern "C" #define FGMAC_DMA_BUS_SWR BIT(0) /* 软件复位 */ #define FGMAC_DMA_BUS_DA BIT(1) /* 设置 8xPBL 模式 */ #define FGMAC_DMA_BUS_DSL_MASK GENMASK(6, 2) /* 描述符跳跃长度 */ -#define FGMAC_DMA_BUS_ATDS BIT(7) +#define FGMAC_DMA_BUS_ATDS BIT(7) /* #define FGMAC_DMA_BUS_PBL_MASK GENMASK(13, 8) /* 可编程突发长度 */ #define FGMAC_DMA_BUS_PBL(x) ((x) << 8) enum @@ -551,4 +551,4 @@ FError FGmacPhyWaitBusBusy(uintptr base_addr, int timeout); } #endif -#endif +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_intr.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_intr.c index e23aabfb44..fc9af72db5 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_intr.c @@ -14,11 +14,13 @@ * FilePath: fgmac_intr.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  Functions in this file implement general purpose interrupt processing related + * functionality. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_sinit.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_sinit.c index 87822e48b0..4fc31d4153 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/fgmac_sinit.c @@ -14,11 +14,13 @@ * FilePath: fgmac_sinit.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file contains lookup method by device ID when success, it returns + * pointer to config table to be used to initialize the device. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ @@ -39,7 +41,7 @@ /************************** Variable Definitions *****************************/ -extern const FGmacConfig FGMAC_CONFIG_TBL[GMAC_INSTANCE_NUM]; +extern const FGmacConfig FGMAC_CONFIG_TBL[FGMAC_NUM]; /************************** Function Prototypes ******************************/ /** @@ -55,7 +57,7 @@ const FGmacConfig *FGmacLookupConfig(u32 instance_id) const FGmacConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)GMAC_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FGMAC_NUM; index++) { if (FGMAC_CONFIG_TBL[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.c index 038afa1ede..941d7d66b8 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.c @@ -14,11 +14,12 @@ * FilePath: fgmac_ar803x.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for ar803x PHYs chip * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ @@ -78,7 +79,9 @@ static FError FGmacAr803xDebugRegRead(FGmac *instance_p, u32 phy_address, u16 de ret = FGmacWritePhyReg(instance_p, phy_address, FGMAC_AR803X_DEBUG_ADDR, debug_reg & FGMAC_AR803X_DEBUG_DATA_MASK); if (FGMAC_SUCCESS != ret) + { return ret; + } ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_AR803X_DEBUG_DATA, reg_data_p); return ret; @@ -92,7 +95,9 @@ static FError FGmacAr803xMaskReg(FGmac *instance_p, u32 phy_address, u16 reg, u3 ret = FGmacReadPhyReg(instance_p, phy_address, reg, &val); if (FGMAC_SUCCESS != ret) + { return ret; + } val &= ~clear; val |= set; @@ -115,14 +120,16 @@ FError FGmacAr803xDisableHibernate(FGmac *instance_p) ret = FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_DEBUG_HIB_CTRL_REG, ®_val); if (FGMAC_SUCCESS != ret) + { return ret; + } reg_val &= ~FGMAC_AR803X_PS_HIB_EN; ret = FGmacWritePhyReg(instance_p, instance_p->phy_addr, FGMAC_AR803X_DEBUG_DATA, reg_val); reg_val = 0; FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_DEBUG_HIB_CTRL_REG, ®_val); - FGMAC_INFO("debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); + FGMAC_INFO("Debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); return ret; } @@ -142,7 +149,9 @@ FError FFmacAr803xRxClockDelayControl(FGmac *instance_p, u32 enable_setting) ret = FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_RX_CLOCK_CTRL_REG, ®_val); if (FGMAC_SUCCESS != ret) + { return ret; + } if (enable_setting == FGMAC_RX_CLOCK_ENABLE) { @@ -157,7 +166,7 @@ FError FFmacAr803xRxClockDelayControl(FGmac *instance_p, u32 enable_setting) reg_val = 0; FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_RX_CLOCK_CTRL_REG, ®_val); - FGMAC_INFO("debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); + FGMAC_INFO("Debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); return ret; } @@ -177,7 +186,9 @@ FError FFmacAr803xTxClockDelayControl(FGmac *instance_p, u32 enable_setting) ret = FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_TX_CLOCK_CTRL_REG, ®_val); if (FGMAC_SUCCESS != ret) + { return ret; + } if (enable_setting == FGMAC_TX_CLOCK_ENABLE) { @@ -192,7 +203,7 @@ FError FFmacAr803xTxClockDelayControl(FGmac *instance_p, u32 enable_setting) reg_val = 0; FGmacAr803xDebugRegRead(instance_p, instance_p->phy_addr, FGMAC_AR803X_TX_CLOCK_CTRL_REG, ®_val); - FGMAC_INFO("debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); + FGMAC_INFO("Debug reg: 0x%lx, ret: 0x%lx", reg_val, ret); return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.h b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.h index 324583dca3..65defb514d 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/ar803x/fgmac_ar803x.h @@ -14,29 +14,29 @@ * FilePath: fgmac_ar803x.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for This file is for ar803x PHYs chip * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ -#ifndef DRIVERS_FGMAC_PHY_AR803X_H -#define DRIVERS_FGMAC_PHY_AR803X_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FGMAC_AR803X_H +#define FGMAC_AR803X_H /***************************** Include Files *********************************/ #include "ftypes.h" #include "fassert.h" - #include "fgmac_phy.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /* phy id */ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.c b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.c index 53b0d65ada..562544262b 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.c @@ -14,11 +14,15 @@ * FilePath: fgmac_phy.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:53 - * Description:  This file is for + * Description:  This file implements functionalities to: + * Detect the available PHYs connected to a MAC + * Negotiate speed + * Configure speed * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ /***************************** Include Files *********************************/ @@ -28,16 +32,16 @@ #include "ferror_code.h" #include "ftypes.h" #include "fdebug.h" - #include "fparameters.h" - #include "fgmac_hw.h" #include "fgmac_phy.h" #include "fgmac.h" +#include "fsleep.h" +#include "sdkconfig.h" + #ifdef CONFIG_FGMAC_PHY_AR803X #include "fgmac_ar803x.h" #endif -#include "fsleep.h" /************************** Constant Definitions *****************************/ @@ -84,20 +88,24 @@ static FError FGmacWaitPhyAutoNegotiationEnd(FGmac *instance_p, u32 phy_address) reg_val = 0; ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_PHY_MII_STATUS_REG, ®_val); if (FGMAC_SUCCESS != ret) + { break; + } fsleep_millisec(20); } while ((FGMAC_PHY_MII_SR_AUTO_NEGOT_COMPLETE != (FGMAC_PHY_MII_SR_AUTO_NEGOT_COMPLETE & reg_val)) && - (0 < --timeout)); + (0 < --timeout)); if (FGMAC_SUCCESS != ret) + { return ret; + } if (0 >= timeout) { - FGMAC_ERROR("auto negotiation timeout, reg_val: %#x", reg_val); + FGMAC_ERROR("Auto negotiation timeout, reg_val: %#x", reg_val); ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, ®_val); - FGMAC_ERROR("auto negotiation timeout, FGMAC_PHY_MII_CTRL_REG reg_val: %#x", reg_val); + FGMAC_ERROR("Auto negotiation timeout, FGMAC_PHY_MII_CTRL_REG reg_val: %#x", reg_val); ret = FGMAC_ERR_TIMEOUT; } @@ -123,7 +131,9 @@ static FError FGmacPhyAutoNegotiation(FGmac *instance_p, u32 phy_address) reg_val = 0; ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_PHY_MII_STATUS_REG, ®_val); if (FGMAC_SUCCESS != ret) + { break; + } fsleep_millisec(20); } @@ -131,17 +141,19 @@ static FError FGmacPhyAutoNegotiation(FGmac *instance_p, u32 phy_address) if (0 >= timeout) { - FGMAC_ERROR("timeout when wait phy auto negotiation "); + FGMAC_ERROR("Timeout when wait phy auto negotiation."); return FGMAC_ERR_TIMEOUT; } if (FGMAC_SUCCESS != ret) + { return ret; + } ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, ®_val); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("auto negotiation failed"); + FGMAC_ERROR("Auto negotiation failed."); return ret; } @@ -150,13 +162,15 @@ static FError FGmacPhyAutoNegotiation(FGmac *instance_p, u32 phy_address) ret = FGmacWritePhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, reg_val); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("auto negotiation failed"); + FGMAC_ERROR("Auto negotiation failed."); return ret; } ret = FGmacWaitPhyAutoNegotiationEnd(instance_p, phy_address); if (FGMAC_SUCCESS != ret) + { return ret; + } return ret; } @@ -177,32 +191,38 @@ static FError FGmacPhyNoneNegotiation(FGmac *instance_p, u32 phy_address) /* read phy control register */ ret = FGmacReadPhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, &control_reg); if (FGMAC_SUCCESS != ret) + { return ret; + } /* 设置半双工模式 */ if (FGMAC_PHY_MODE_FULLDUPLEX == instance_p->config.duplex_mode) + { control_reg |= FGMAC_PHY_MII_CR_DUPLEX_MODE; + } else + { control_reg &= ~(FGMAC_PHY_MII_CR_DUPLEX_MODE); + } /* 设置速度bit6|bit13, 10b-1000M, 01b-100M, 00b-10M */ switch (instance_p->config.speed) { - case FGMAC_PHY_SPEED_1000: - control_reg |= FGMAC_PHY_MII_CR_SPEED_SEL_MSB; - control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_LSB); - break; - case FGMAC_PHY_SPEED_100: - control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_MSB); - control_reg |= FGMAC_PHY_MII_CR_SPEED_SEL_LSB; - break; - case FGMAC_PHY_SPEED_10: - control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_MSB); - control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_LSB); - break; - default: - FASSERT(0); - break; + case FGMAC_PHY_SPEED_1000: + control_reg |= FGMAC_PHY_MII_CR_SPEED_SEL_MSB; + control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_LSB); + break; + case FGMAC_PHY_SPEED_100: + control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_MSB); + control_reg |= FGMAC_PHY_MII_CR_SPEED_SEL_LSB; + break; + case FGMAC_PHY_SPEED_10: + control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_MSB); + control_reg &= ~(FGMAC_PHY_MII_CR_SPEED_SEL_LSB); + break; + default: + FASSERT(0); + break; } /* disable auto-negotiation */ @@ -213,7 +233,7 @@ static FError FGmacPhyNoneNegotiation(FGmac *instance_p, u32 phy_address) ret = FGmacWritePhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, control_reg); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("disable auto-negotiation failed"); + FGMAC_ERROR("Disable auto negotiation failed."); return ret; } @@ -273,13 +293,17 @@ FError FGmacReadPhyReg(FGmac *instance_p, u32 phy_address, u16 phy_reg, u16 *phy ret = FGmacPhyWaitBusBusy(base_addr, FGMAC_RETRY_TIMES); if (FGMAC_SUCCESS != ret) + { return ret; + } FGMAC_WRITE_REG32(base_addr, FGMAC_GMII_ADDR_OFFSET, cmd_reg_val); ret = FGmacPhyWaitBusBusy(base_addr, FGMAC_RETRY_TIMES); if (FGMAC_SUCCESS != ret) + { return ret; + } *phy_reg_val_p = FGMAC_MII_DATA_GD_MASK & FGMAC_READ_REG32(base_addr, FGMAC_GMII_DATA_OFFSET); return ret; @@ -303,7 +327,7 @@ FError FGmacPhyDetect(FGmac *instance_p) ret = FGmacReadPhyReg(instance_p, phy_addr, FGMAC_PHY_MII_STATUS_REG, &phy_reg); if (ret != FGMAC_SUCCESS) { - FGMAC_ERROR("%s, PHY operation is busy", __func__); + FGMAC_ERROR("%s, phy operation is busy.", __func__); return ret; } @@ -319,7 +343,7 @@ FError FGmacPhyDetect(FGmac *instance_p) instance_p->phy_valid_mask |= (1 << phy_addr); instance_p->phy_id1 = phy_id1_reg; - FGMAC_INFO("phy_addr: [%d], phy_valid_mask: 0x%x, phy id: [0x%08x][0x%08x], phy_reg:0x%x", + FGMAC_INFO("Phy_addr: [%d], phy_valid_mask: 0x%x, phy id: [0x%08x][0x%08x], phy_reg:0x%x", phy_addr, instance_p->phy_valid_mask, phy_id1_reg, phy_id2_reg, phy_reg); return ret; @@ -333,7 +357,7 @@ FError FGmacPhyDetect(FGmac *instance_p) if (invalid_count == FGMAC_PHY_MAX_NUM) { - FGMAC_ERROR("phy detect failed, phy address is not found!"); + FGMAC_ERROR("Phy detect failed, phy address is not found!"); return FGMAC_ERR_PHY_IS_NOT_FOUND; } @@ -354,7 +378,7 @@ FError FGmacPhyReset(FGmac *instance_p, u32 phy_address) ret = FGmacWritePhyReg(instance_p, phy_address, FGMAC_PHY_MII_CTRL_REG, FGMAC_PHY_MII_CR_RESET); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("reset phy failed"); + FGMAC_ERROR("Reset phy failed."); return ret; } return FGMAC_SUCCESS; @@ -380,23 +404,27 @@ static FError FGmacGetPhySpecialStatus(FGmac *instance_p, u32 phy_address) switch (phy_special_status & FGMAC_PHY_SPECIFIC_STATUS_SPEED_MASK) { - case FGMAC_PHY_SPECIFIC_STATUS_SPEED_1000M: - instance_p->config.speed = FGMAC_PHY_SPEED_1000; - break; - case FGMAC_PHY_SPECIFIC_STATUS_SPEED_100M: - instance_p->config.speed = FGMAC_PHY_SPEED_100; - break; - case FGMAC_PHY_SPECIFIC_STATUS_SPEED_10M: - instance_p->config.speed = FGMAC_PHY_SPEED_10; - break; - default: - break; + case FGMAC_PHY_SPECIFIC_STATUS_SPEED_1000M: + instance_p->config.speed = FGMAC_PHY_SPEED_1000; + break; + case FGMAC_PHY_SPECIFIC_STATUS_SPEED_100M: + instance_p->config.speed = FGMAC_PHY_SPEED_100; + break; + case FGMAC_PHY_SPECIFIC_STATUS_SPEED_10M: + instance_p->config.speed = FGMAC_PHY_SPEED_10; + break; + default: + break; } if (phy_special_status & FGMAC_PHY_SPECIFIC_STATUS_DUPLEX_MASK) + { instance_p->config.duplex_mode = FGMAC_PHY_MODE_FULLDUPLEX; + } else + { instance_p->config.duplex_mode = FGMAC_PHY_MODE_HALFDUPLEX; + } return ret; } @@ -418,7 +446,7 @@ FError FGmacPhyCfgInitialize(FGmac *instance_p) ret = FGmacPhyDetect(instance_p); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("phy detect failed!"); + FGMAC_ERROR("Phy detect failed!"); return ret; } @@ -436,7 +464,7 @@ FError FGmacPhyCfgInitialize(FGmac *instance_p) ret = FGmacPhyAutoNegotiation(instance_p, phy_addr); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("auto negotiation phy failed"); + FGMAC_ERROR("Auto negotiation phy failed."); return ret; } } @@ -446,7 +474,7 @@ FError FGmacPhyCfgInitialize(FGmac *instance_p) ret = FGmacPhyNoneNegotiation(instance_p, phy_addr); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("negotiation phy failed"); + FGMAC_ERROR("Negotiation phy failed."); return ret; } } @@ -455,7 +483,7 @@ FError FGmacPhyCfgInitialize(FGmac *instance_p) ret = FGmacGetPhySpecialStatus(instance_p, phy_addr); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("get phy special status failed"); + FGMAC_ERROR("Get phy special status failed."); return ret; } @@ -505,7 +533,7 @@ FError FGmacPhyAwaken(FGmac *instance_p) ret = FGmacPhyDetect(instance_p); if (FGMAC_SUCCESS != ret) { - FGMAC_ERROR("phy detect failed!"); + FGMAC_ERROR("Phy detect failed!"); return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.h b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.h index 6287745cf3..8ce0ef797f 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fgmac/phy/fgmac_phy.h @@ -14,16 +14,24 @@ * FilePath: fgmac_phy.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file implements functionalities to: + * Detect the available PHYs connected to a MAC + * Negotiate speed + * Configure speed * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/07/13 first release */ +#ifndef FGMAC_PHY_H +#define FGMAC_PHY_H -#ifndef DRIVERS_ETH_FGMAC_PHY_H -#define DRIVERS_ETH_FGMAC_PHY_H +#include "ftypes.h" +#include "fassert.h" +#include "fkernel.h" +#include "fgmac.h" #ifdef __cplusplus extern "C" @@ -32,11 +40,6 @@ extern "C" /***************************** Include Files *********************************/ -#include "ftypes.h" -#include "fassert.h" -#include "fkernel.h" -#include "fgmac.h" - /************************** Constant Definitions *****************************/ #define FGMAC_PHY_MAX_NUM 32U @@ -205,6 +208,7 @@ FError FGmacReadPhyReg(FGmac *instance_p, u32 phy_address, u16 phy_reg, u16 *phy FError FGmacPhyCfgDeInitialize(FGmac *instance_p); FError FGmacPhyAwaken(FGmac *instance_p); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.c index ffdca1ffbf..4b03f2782d 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.c @@ -14,11 +14,13 @@ * FilePath: fxmac.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for xmac driver .Functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac.h" @@ -39,6 +41,43 @@ static void FXmacReset(FXmac *instance_p); extern FError FXmacSetTypeIdCheck(FXmac *instance_p, u32 id_check, u8 index); + +static void FXmacHighSpeedConfiguration(FXmac *instance_p,u32 speed) +{ + u32 reg_value; + s32 set_speed = 0; + switch (speed) + { + case FXMAC_SPEED_25000: + set_speed = 2; + break; + case FXMAC_SPEED_10000: + set_speed = 4; + break; + case FXMAC_SPEED_5000: + set_speed = 3; + break; + case FXMAC_SPEED_2500: + set_speed = 2; + break; + case FXMAC_SPEED_1000: + set_speed = 1; + break; + default: + set_speed = 0; + break; + } + /*GEM_HSMAC(0x0050) provide rate to the external*/ + reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC); + reg_value &= ~FXMAC_GEM_HSMACSPEED_MASK; + reg_value |= (set_speed) &FXMAC_GEM_HSMACSPEED_MASK; + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC, reg_value); + + reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC); + + FXMAC_PRINT_I("FXMAC_GEM_HSMAC is %x \r\n ", reg_value); +} + /** * @name: FXmacSelectClk * @msg: Determine the driver clock configuration based on the media independent interface @@ -46,10 +85,10 @@ extern FError FXmacSetTypeIdCheck(FXmac *instance_p, u32 id_check, u8 index); * @param {u32} speed interface speed * @return {*} */ -void FXmacSelectClk(FXmac *instance_p) +void FXmacSelectClkOld(FXmac *instance_p) { u32 reg_value; - s32 set_speed = 0; + u32 speed = instance_p->config.speed; FASSERT(instance_p != NULL); FASSERT((speed == FXMAC_SPEED_10) || (speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_1000) || (speed == FXMAC_SPEED_2500) || (speed == FXMAC_SPEED_10000)); @@ -64,6 +103,35 @@ void FXmacSelectClk(FXmac *instance_p) FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1); } } + else if(instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_5GBASER) + { + if(speed == FXMAC_SPEED_5000) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x8); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x0); + } + } + else if(instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_2500BASEX) + { + if(speed == FXMAC_SPEED_25000) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_PMA_XCVR_POWER_STATE, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/ + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/ + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/ + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0); /*0x1c7c*/ + } + } else if (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) { FXMAC_PRINT_I("FXMAC_PHY_INTERFACE_MODE_SGMII init"); @@ -174,39 +242,39 @@ void FXmacSelectClk(FXmac *instance_p) FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/ } - - switch (speed) - { - case FXMAC_SPEED_25000: - set_speed = 2; - break; - case FXMAC_SPEED_10000: - set_speed = 4; - break; - case FXMAC_SPEED_5000: - set_speed = 3; - break; - case FXMAC_SPEED_2500: - set_speed = 2; - break; - case FXMAC_SPEED_1000: - set_speed = 1; - break; - default: - set_speed = 0; - break; - } - /*GEM_HSMAC(0x0050) provide rate to the external*/ - reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC); - reg_value &= ~FXMAC_GEM_HSMACSPEED_MASK; - reg_value |= (set_speed) &FXMAC_GEM_HSMACSPEED_MASK; - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC, reg_value); - - reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_HSMAC); - - FXMAC_PRINT_I("FXMAC_GEM_HSMAC is %x \r\n ", reg_value); + FXmacHighSpeedConfiguration(instance_p,speed); } +void FXmacSelectClk(FXmac *instance_p) +{ + u32 reg_value; + + u32 speed = instance_p->config.speed; + FASSERT(instance_p != NULL); + FASSERT((speed == FXMAC_SPEED_10) || (speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_1000) || (speed == FXMAC_SPEED_2500) || (speed == FXMAC_SPEED_10000)); + FXMAC_PRINT_I("************* FXmacSelectClk *************** "); + if (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) + { + FXMAC_PRINT_I("FXMAC_PHY_INTERFACE_MODE_SGMII init"); + if ((speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_10)) + { + FXMAC_PRINT_I("speed IS %d \r\n",speed); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x1); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); + } + } + + if(speed == FXMAC_SPEED_10000) + { + FXMAC_PRINT_I("FXMAC_SPEED_10000 is not set high speed\r\n"); + } + else + { + FXmacHighSpeedConfiguration(instance_p,speed); + } +} + + /** * Start the Ethernet controller as follows: * - Enable transmitter if FXMAC_TRANSMIT_ENABLE_OPTION is set @@ -403,6 +471,20 @@ static u32 FXmacClkDivGet(FXmac *instance_p) } } +static u32 FXmacConfigureCaps(FXmac *instance_p) +{ + u32 read_regs = 0; + FXmacConfig *config_p; + instance_p->caps = 0; + config_p = &instance_p->config; + read_regs = FXMAC_READREG32(config_p->base_address, FXMAC_DESIGNCFG_DEBUG1_OFFSET); + if((read_regs&FXMAC_DESIGNCFG_DEBUG1_BUS_IRQCOR_MASK) == 0) + { + instance_p->caps |= FXMAC_CAPS_ISR_CLEAR_ON_WRITE; + FXMAC_PRINT_I("Has FXMAC_CAPS_ISR_CLEAR_ON_WRITE feature"); + } +} + static u32 FXmacDmaWidth(FXmac *instance_p) { u32 read_regs = 0; @@ -418,15 +500,15 @@ static u32 FXmacDmaWidth(FXmac *instance_p) switch ((read_regs & FXMAC_DESIGNCFG_DEBUG1_BUS_WIDTH_MASK) >> 25) { - case 4: - FXMAC_PRINT_I("bus width is 128"); - return FXMAC_NWCFG_BUS_WIDTH_128_MASK; - case 2: - FXMAC_PRINT_I("bus width is 64"); - return FXMAC_NWCFG_BUS_WIDTH_64_MASK; - default: - FXMAC_PRINT_I("bus width is 32"); - return FXMAC_NWCFG_BUS_WIDTH_32_MASK; + case 4: + FXMAC_PRINT_I("bus width is 128"); + return FXMAC_NWCFG_BUS_WIDTH_128_MASK; + case 2: + FXMAC_PRINT_I("bus width is 64"); + return FXMAC_NWCFG_BUS_WIDTH_64_MASK; + default: + FXMAC_PRINT_I("bus width is 32"); + return FXMAC_NWCFG_BUS_WIDTH_32_MASK; } } @@ -546,9 +628,9 @@ static void FXmacReset(FXmac *instance_p) FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_NWCTRL_OFFSET, ((FXMAC_NWCTRL_STATCLR_MASK) & (u32)(~FXMAC_NWCTRL_LOOPEN_MASK)) | FXMAC_NWCTRL_MDEN_MASK); - + FXmacConfigureCaps(instance_p); write_reg = FXmacClkDivGet(instance_p); /* mdio clock division */ - write_reg |= FXmacDmaWidth(instance_p); /* 位宽 */ + write_reg |= FXmacDmaWidth(instance_p); /* DMA位宽 */ FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_NWCFG_OFFSET, write_reg); @@ -582,7 +664,7 @@ static void FXmacReset(FXmac *instance_p) /* clear all counters */ for (i = 0U; i < (u8)((FXMAC_LAST_OFFSET - FXMAC_OCTTXL_OFFSET) / 4U); - i++) + i++) { (void)FXMAC_READREG32(instance_p->config.base_address, FXMAC_OCTTXL_OFFSET + (u32)(((u32)i) * ((u32)4))); @@ -609,7 +691,7 @@ void FXmacInitInterface(FXmac *instance_p) FXmacConfig *config_p; config_p = &instance_p->config; - if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_XGMII) + if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_XGMII ) { config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET); config &= ~FXMAC_NWCFG_PCSSEL_MASK; @@ -621,29 +703,37 @@ void FXmacInitInterface(FXmac *instance_p) config_p->duplex = 1; } - else if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_USXGMII) + else if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_USXGMII || config_p->interface == FXMAC_PHY_INTERFACE_MODE_5GBASER) { + FXMAC_PRINT_I("usx interface is %d",config_p->interface); + /* network_config */ + config_p->duplex = 1; config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET); config |= FXMAC_NWCFG_PCSSEL_MASK; + config &= ~FXMAC_NWCFG_100_MASK; + config &= ~FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK; + if (config_p->duplex == 1) + { + FXMAC_PRINT_I("is duplex"); + config |= FXMAC_NWCFG_FDEN_MASK; + } + FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config); + /* network_control */ control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET); control |= FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */ FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control); - + + + /* High speed PCS control register */ control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET); - control &= ~(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS); - control |= FXMAC_GEM_USX_RX_SYNC_RESET; - FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control); - - control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET); - control &= ~FXMAC_GEM_USX_RX_SYNC_RESET; - control |= FXMAC_GEM_USX_TX_DATAPATH_EN; - control |= FXMAC_GEM_USX_SIGNAL_OK; - + if (config_p->speed == FXMAC_SPEED_10000) { + FXMAC_PRINT_I("is 10G"); control |= FXMAC_GEM_USX_HS_MAC_SPEED_10G; + control |= FXMAC_GEM_USX_SERDES_RATE_10G; } else if (config_p->speed == FXMAC_SPEED_25000) { @@ -657,16 +747,70 @@ void FXmacInitInterface(FXmac *instance_p) { control |= FXMAC_GEM_USX_HS_MAC_SPEED_100M; } + else if(config_p->speed == FXMAC_SPEED_5000) + { + control |= FXMAC_GEM_USX_HS_MAC_SPEED_5G; + control |= FXMAC_GEM_USX_SERDES_RATE_5G; + } + + control &= ~(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS); + control |= FXMAC_GEM_USX_RX_SYNC_RESET; + FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control); + + control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET); + control &= ~FXMAC_GEM_USX_RX_SYNC_RESET; + control |= FXMAC_GEM_USX_TX_DATAPATH_EN; + control |= FXMAC_GEM_USX_SIGNAL_OK; FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control); + + } + else if(config_p->interface == FXMAC_PHY_INTERFACE_MODE_2500BASEX) + { + /* network_config */ config_p->duplex = 1; + config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET); + config |= FXMAC_NWCFG_PCSSEL_MASK | FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK; + config &= ~FXMAC_NWCFG_100_MASK; + + if (config_p->duplex == 1) + { + config |= FXMAC_NWCFG_FDEN_MASK; + } + FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config); + + /* network_control */ + control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET); + control &= ~FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; + control |= FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK; /* Use high speed MAC */ + FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, control); + + /* High speed PCS control register */ + control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET); + + if (config_p->speed == FXMAC_SPEED_25000) + { + control |= FXMAC_GEM_USX_HS_MAC_SPEED_2_5G; + } + + control &= ~(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS); + control |= FXMAC_GEM_USX_RX_SYNC_RESET; + FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control); + + control = FXMAC_READREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET); + control &= ~FXMAC_GEM_USX_RX_SYNC_RESET; + control |= FXMAC_GEM_USX_TX_DATAPATH_EN; + control |= FXMAC_GEM_USX_SIGNAL_OK; + + FXMAC_WRITEREG32(config_p->base_address, FXMAC_GEM_USX_CONTROL_OFFSET, control); + } else if (config_p->interface == FXMAC_PHY_INTERFACE_MODE_SGMII) { config = FXMAC_READREG32(config_p->base_address, FXMAC_NWCFG_OFFSET); config |= FXMAC_NWCFG_PCSSEL_MASK | FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK; - config &= ~(FXMAC_NWCFG_100_MASK | FXMAC_NWCFG_FDEN_MASK); + config &= ~(FXMAC_NWCFG_100_MASK | FXMAC_NWCFG_FDEN_MASK|FXMAC_NWCFG_LENGTH_FIELD_ERROR_FRAME_DISCARD); if (instance_p->moudle_id >= 2) { @@ -738,11 +882,6 @@ void FXmacInitInterface(FXmac *instance_p) config |= FXMAC_NWCFG_1000_MASK; } - if (config_p->duplex) - { - config |= FXMAC_NWCFG_FDEN_MASK; - } - FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCFG_OFFSET, config); control = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET); @@ -751,7 +890,6 @@ void FXmacInitInterface(FXmac *instance_p) } } - static void FXmacIrqStubHandler(void) { FASSERT_MSG(0, "Please register the interrupt callback function"); diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.h index 19678d929c..a0182db38c 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac.h @@ -14,29 +14,30 @@ * FilePath: fxmac.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for gmac driver .Functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef DRIVERS_ETH_F_XMAC_H -#define DRIVERS_ETH_F_XMAC_H +#ifndef FXMAC_H +#define FXMAC_H + +#include "ftypes.h" +#include "fassert.h" +#include "ferror_code.h" +#include "fxmac_hw.h" +#include "fxmac_bdring.h" +#include "fparameters.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fassert.h" -#include "ferror_code.h" - -#include "fxmac_hw.h" -#include "fxmac_bdring.h" -#include "fparameters.h" - #define FXMAC_ERR_INVALID_PARAM FT_MAKE_ERRCODE(ErrModBsp, ErrBspEth, 0x1u) #define FXMAC_ERR_SG_LIST FT_MAKE_ERRCODE(ErrModBsp, ErrBspEth, 0x2u) #define FXMAC_ERR_GENERAL FT_MAKE_ERRCODE(ErrModBsp, ErrBspEth, 0x4u) @@ -159,7 +160,7 @@ typedef enum #define FXMAC_MAX_VLAN_FRAME_SIZE (FXMAC_MTU + FXMAC_HDR_SIZE + \ FXMAC_HDR_VLAN_SIZE + FXMAC_TRL_SIZE) #define FXMAC_MAX_VLAN_FRAME_SIZE_JUMBO (FXMAC_MTU_JUMBO + FXMAC_HDR_SIZE + \ - FXMAC_HDR_VLAN_SIZE + FXMAC_TRL_SIZE) + FXMAC_HDR_VLAN_SIZE + FXMAC_TRL_SIZE) #define FXMAC_MAX_FRAME_SIZE_JUMBO (FXMAC_MTU_JUMBO + FXMAC_HDR_SIZE + FXMAC_TRL_SIZE) @@ -186,6 +187,10 @@ typedef enum #define FXMAC_SPEED_10000 10000U #define FXMAC_SPEED_25000 25000U +/* Capability mask bits */ +#define FXMAC_CAPS_ISR_CLEAR_ON_WRITE 0x00000001 /* irq status parameters need to be written to clear after they have been read */ + + /** @name Direction identifiers * * These are used by several functions and callbacks that need @@ -226,6 +231,8 @@ typedef enum FXMAC_PHY_INTERFACE_MODE_RGMII, FXMAC_PHY_INTERFACE_MODE_XGMII, FXMAC_PHY_INTERFACE_MODE_USXGMII, + FXMAC_PHY_INTERFACE_MODE_5GBASER , + FXMAC_PHY_INTERFACE_MODE_2500BASEX } FXmacPhyInterface; typedef struct @@ -240,12 +247,13 @@ typedef struct u32 auto_neg; /* Enable auto-negotiation - when set active high, autonegotiation operation is enabled. */ u32 pclk_hz; u32 max_queue_num; /* Number of Xmac Controller Queues */ - u32 tx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ - u32 rx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 tx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 rx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ u32 hotplug_irq_num; u32 dma_brust_length; /* burst length */ u32 network_default_config; - u32 queue_irq_num[FT_XMAC_QUEUE_MAX_NUM]; /* mac0 8个 ,其他的 4个 */ + u32 queue_irq_num[FXMAC_QUEUE_MAX_NUM]; /* mac0 8个 ,其他的 4个 */ + u32 caps; /* */ } FXmacConfig; typedef struct @@ -261,6 +269,7 @@ typedef struct u32 is_started; u32 link_status; /* indicates link status ,FXMAC_LINKUP is link up ,FXMAC_LINKDOWN is link down,FXMAC_NEGOTIATING is need to negotiating*/ u32 options; + u32 caps; /* Capability mask bits */ FXmacQueue tx_bd_queue; /* Transmit Queue */ FXmacQueue rx_bd_queue; /* Receive Queue */ @@ -302,6 +311,7 @@ FError FXmacSetMacAddress(FXmac *instance_p, u8 *address_ptr, u8 index); FError FXmacSetOptions(FXmac *instance_p, u32 options, u32 queue_num); FError FXmacClearOptions(FXmac *instance_p, u32 options, u32 queue_num); +boolean FXmacUsxLinkStatus(FXmac *instance_p); void FXmacStart(FXmac *instance_p); void FXmacStop(FXmac *instance_p); @@ -325,6 +335,12 @@ void FXmacIntrHandler(s32 vector, void *args); void FXmacClearHash(FXmac *instance_p); + +/* debug */ +void FXmacDebugTxPrint(FXmac *instance_p); +void FXmacDebugRxPrint(FXmac *instance_p); +void FXmacDebugUsxPrint(FXmac *instance_p); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bd.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bd.h index bbe982340d..203e39e1b5 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bd.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bd.h @@ -14,24 +14,25 @@ * FilePath: fxmac_bd.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for buffer descriptor (BD) management API. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef DRIVERS_ETH_F_XMAC_BD_H -#define DRIVERS_ETH_F_XMAC_BD_H +#ifndef FXMAC_BD_H +#define FXMAC_BD_H + +#include "ftypes.h" +#include "string.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "string.h" - /** * @name: FXMAC_BD_READ @@ -64,7 +65,7 @@ extern "C" */ #define FXMAC_BD_SET_STATUS(bd_ptr, data) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) | (data)) + FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) | (data)) /** @@ -75,8 +76,8 @@ extern "C" #define FXMAC_BD_IS_RX_NEW(bd_ptr) \ ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ FXMAC_RXBUF_NEW_MASK) != 0U \ - ? TRUE \ - : FALSE) + ? TRUE \ + : FALSE) /** @@ -88,8 +89,8 @@ extern "C" #define FXMAC_BD_IS_TX_WRAP(bd_ptr) \ ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ FXMAC_TXBUF_WRAP_MASK) != 0U \ - ? TRUE \ - : FALSE) + ? TRUE \ + : FALSE) /** @@ -101,8 +102,8 @@ extern "C" #define FXMAC_BD_IS_RX_WRAP(bd_ptr) \ ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ FXMAC_RXBUF_WRAP_MASK) != 0U \ - ? TRUE \ - : FALSE) + ? TRUE \ + : FALSE) @@ -115,9 +116,9 @@ extern "C" #if defined(__aarch64__) || defined(__arch64__) #define FXMAC_BD_SET_ADDRESS_TX(bd_ptr, addr) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_OFFSET, \ - (u32)((addr)&ULONG64_LO_MASK)); \ + (u32)((addr)&ULONG64_LO_MASK)); \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_HI_OFFSET, \ - (u32)(((addr)&ULONG64_HI_MASK) >> 32U)); + (u32)(((addr)&ULONG64_HI_MASK) >> 32U)); #else #define FXMAC_BD_SET_ADDRESS_TX(bd_ptr, addr) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_OFFSET, (u32)(addr)) @@ -134,17 +135,17 @@ extern "C" #ifdef __aarch64__ #define FXMAC_BD_SET_ADDRESS_RX(bd_ptr, addr) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_OFFSET, \ - ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ - ~FXMAC_RXBUF_ADD_MASK) | \ - ((u32)((addr)&ULONG64_LO_MASK)))); \ + ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ + ~FXMAC_RXBUF_ADD_MASK) | \ + ((u32)((addr)&ULONG64_LO_MASK)))); \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_HI_OFFSET, \ - (u32)(((addr)&ULONG64_HI_MASK) >> 32U)); + (u32)(((addr)&ULONG64_HI_MASK) >> 32U)); #else #define FXMAC_BD_SET_ADDRESS_RX(bd_ptr, addr) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_ADDR_OFFSET, \ - ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ - ~FXMAC_RXBUF_ADD_MASK) | \ - (u32)(addr))) + ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_ADDR_OFFSET) & \ + ~FXMAC_RXBUF_ADD_MASK) | \ + (u32)(addr))) #endif @@ -158,9 +159,9 @@ extern "C" */ #define FXMAC_BD_SET_LENGTH(bd_ptr, len_bytes) \ FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ - ~FXMAC_TXBUF_LEN_MASK) | \ - (len_bytes))) + ((FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ + ~FXMAC_TXBUF_LEN_MASK) | \ + (len_bytes))) /** @@ -174,6 +175,10 @@ extern "C" (FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ FXMAC_RXBUF_LEN_MASK) +#define FXMAC_BD_GET_TX_LENGTH(bd_ptr) \ + (FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ + FXMAC_TXBUF_LEN_MASK) + /** * @name: FXMAC_GET_RX_FRAME_SIZE @@ -190,7 +195,7 @@ extern "C" #define FXMAC_GET_RX_FRAME_SIZE(instance_p, bd_ptr) \ (FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ - 0x00003FFFU) + 0x00003FFFU) @@ -204,13 +209,13 @@ extern "C" */ #define FXMAC_BD_CLEAR_TX_USED(bd_ptr) \ (FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ - (~FXMAC_TXBUF_USED_MASK))) + FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ + (~FXMAC_TXBUF_USED_MASK))) #define FXMAC_BD_SET_CRC(bd_ptr) \ (FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ - (~FXMAC_TXBUF_NOCRC_MASK))) + FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ + (~FXMAC_TXBUF_NOCRC_MASK))) /** @@ -222,8 +227,8 @@ extern "C" */ #define FXMAC_BD_SET_LAST(bd_ptr) \ (FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) | \ - FXMAC_TXBUF_LAST_MASK)) + FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) | \ + FXMAC_TXBUF_LAST_MASK)) /** @@ -235,8 +240,8 @@ extern "C" */ #define FXMAC_BD_CLEAR_LAST(bd_ptr) \ (FXMAC_BD_WRITE((bd_ptr), FXMAC_BD_STAT_OFFSET, \ - FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ - ~FXMAC_TXBUF_LAST_MASK)) + FXMAC_BD_READ((bd_ptr), FXMAC_BD_STAT_OFFSET) & \ + ~FXMAC_TXBUF_LAST_MASK)) /** * @name: FXMAC_BD_CLEAR diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.c index 5459203c18..213ba90b23 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.c @@ -14,11 +14,12 @@ * FilePath: fxmac_bdring.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file implements buffer descriptor ring related functions. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac_hw.h" @@ -49,13 +50,13 @@ static void FXmacBdSetTxWrap(uintptr bdptr); #define FXMAC_RING_SEEKAHEAD(ring_ptr, bdptr, num_bd) \ { \ uintptr addr = (uintptr)(void *)(bdptr); \ - \ + \ addr += ((ring_ptr)->separation * (num_bd)); \ if ((addr > (ring_ptr)->high_bd_addr) || ((uintptr)(void *)(bdptr) > addr)) \ { \ addr -= (ring_ptr)->length; \ } \ - \ + \ (bdptr) = (FXmacBd *)(void *)addr; \ } @@ -72,13 +73,13 @@ static void FXmacBdSetTxWrap(uintptr bdptr); #define FXMAC_RING_SEEKBACK(ring_ptr, bdptr, num_bd) \ { \ uintptr addr = (uintptr)(void *)(bdptr); \ - \ + \ addr -= ((ring_ptr)->separation * (num_bd)); \ if ((addr < (ring_ptr)->base_bd_addr) || ((uintptr)(void *)(bdptr) < addr)) \ { \ addr += (ring_ptr)->length; \ } \ - \ + \ (bdptr) = (FXmacBd *)(void *)addr; \ } @@ -700,15 +701,7 @@ u32 FXmacBdRingFromHwRx(FXmacBdRing *ring_ptr, u32 bd_limit, /* Move on to next BD in work group */ cur_bd_ptr = FXMAC_BD_RING_NEXT(ring_ptr, cur_bd_ptr); - // if((bd_str & FXMAC_RXBUF_EOF_MASK) != 0x00000000U) - // { - // if(bd_str &FXMAC_RXBUF_FCS_STATUS_MASK) - // { - // f_printk("********** error fcs data is appear ************* \r\n"); - // FtDumpHexWord(FXMAC_BD_READ(cur_bd_ptr,0) &(0xfffffff8),bd_str&FXMAC_RXBUF_LEN_MASK); - // f_printk("********** end ************* \r\n"); - // } - // } + } /* Subtract off any partial packet BDs found */ @@ -860,7 +853,7 @@ FError FXmacBdRingCheck(FXmacBdRing *ring_ptr, u8 direction) /* Verify internal counters add up */ if ((ring_ptr->hw_cnt + ring_ptr->pre_cnt + ring_ptr->free_cnt + - ring_ptr->post_cnt) != ring_ptr->all_cnt) + ring_ptr->post_cnt) != ring_ptr->all_cnt) { return (FError)(FXMAC_ERR_SG_LIST); } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.h index b03269e3f4..0f113e6ef0 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_bdring.h @@ -14,24 +14,26 @@ * FilePath: fxmac_bdring.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file ontains DMA channel related structure and constant definition + * as well as function prototypes. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef DRIVERS_ETH_F_XMAC_BDRING_H -#define DRIVERS_ETH_F_XMAC_BDRING_H +#ifndef FXMAC_BDRING_H +#define FXMAC_BDRING_H + +#include "fxmac_bd.h" +#include "ftypes.h" #ifdef __cplusplus extern "C" { #endif -#include "fxmac_bd.h" -#include "ftypes.h" - /**************************** Type Definitions *******************************/ /** This is an internal structure used to maintain the DMA list */ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_debug.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_debug.c new file mode 100644 index 0000000000..d7711c30b8 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_debug.c @@ -0,0 +1,105 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fxmac_debug.c + * Date: 2023-01-04 15:33:03 + * LastEditTime: 2023-01-04 15:33:04 + * Description: This file is for user to debug xmac information. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release + */ + +#include "fxmac_hw.h" +#include "fxmac.h" +#include "fio.h" +#include "fdebug.h" + +#define FXMAC_DEBUG_TAG "FXMAC_DEBUG" +#define FXMAC_ERROR(format, ...) FT_DEBUG_PRINT_E(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_INFO(format, ...) FT_DEBUG_PRINT_I(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_DEBUG(format, ...) FT_DEBUG_PRINT_D(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_WARN(format, ...) FT_DEBUG_PRINT_W(FXMAC_DEBUG_TAG, format, ##__VA_ARGS__) + + +void FXmacDebugTxPrint(FXmac *instance_p) +{ + FXmacConfig *config_p; + config_p = &instance_p->config; + + FXMAC_INFO("octets_txed_bottom is 0x%x",FtIn32(config_p->base_address+FXMAC_OCTTXL_OFFSET)); + FXMAC_INFO("octets_txed_top is 0x%x",FtIn32(config_p->base_address+FXMAC_OCTTXH_OFFSET)); + FXMAC_INFO("frames_txed_ok is 0x%x",FtIn32(config_p->base_address+FXMAC_TXCNT_OFFSET)); + FXMAC_INFO("broadcast_txed is 0x%x",FtIn32(config_p->base_address+FXMAC_TXBCCNT_OFFSET)); + FXMAC_INFO("multicast_txed is 0x%x",FtIn32(config_p->base_address+FXMAC_TXMCCNT_OFFSET)); + FXMAC_INFO("pause_frames_txed is 0x%x",FtIn32(config_p->base_address+FXMAC_TXPAUSECNT_OFFSET)); + FXMAC_INFO("frames_txed_64 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX64CNT_OFFSET)); + FXMAC_INFO("frames_txed_65 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX65CNT_OFFSET)); + FXMAC_INFO("frames_txed_128 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX128CNT_OFFSET)); + FXMAC_INFO("frames_txed_256 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX256CNT_OFFSET)); + FXMAC_INFO("frames_txed_512 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX512CNT_OFFSET)); + FXMAC_INFO("frames_txed_1024 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX1024CNT_OFFSET)); + FXMAC_INFO("frames_txed_1519 is 0x%x",FtIn32(config_p->base_address+FXMAC_TX1519CNT_OFFSET)); + FXMAC_INFO("tx_underruns is 0x%x",FtIn32(config_p->base_address+FXMAC_TXURUNCNT_OFFSET)); + FXMAC_INFO("single_collisions is 0x%x",FtIn32(config_p->base_address+FXMAC_SNGLCOLLCNT_OFFSET)); + FXMAC_INFO("multiple_collisions is 0x%x",FtIn32(config_p->base_address+FXMAC_MULTICOLLCNT_OFFSET)); + FXMAC_INFO("excessive_collisions is 0x%x",FtIn32(config_p->base_address+FXMAC_EXCESSCOLLCNT_OFFSET)); + FXMAC_INFO("late_collisions is 0x%x",FtIn32(config_p->base_address+FXMAC_LATECOLLCNT_OFFSET)); + FXMAC_INFO("deferred_frames is 0x%x",FtIn32(config_p->base_address+FXMAC_TXDEFERCNT_OFFSET)); + FXMAC_INFO("crs_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_TXCSENSECNT_OFFSET)); +} + + +void FXmacDebugRxPrint(FXmac *instance_p) +{ + FXmacConfig *config_p; + config_p = &instance_p->config; + + FXMAC_INFO("octets_rxed_bottom is 0x%x",FtIn32(config_p->base_address+FXMAC_OCTRXL_OFFSET)); + FXMAC_INFO("octets_rxed_top is 0x%x",FtIn32(config_p->base_address+FXMAC_OCTRXH_OFFSET)); + FXMAC_INFO("frames_rxed_ok is 0x%x",FtIn32(config_p->base_address+FXMAC_RXCNT_OFFSET)); + FXMAC_INFO("broadcast_rxed is 0x%x",FtIn32(config_p->base_address+FXMAC_RXBROADCNT_OFFSET)); + FXMAC_INFO("multicast_Rxed is 0x%x",FtIn32(config_p->base_address+FXMAC_RXMULTICNT_OFFSET)); + FXMAC_INFO("pause_frames_rxed is 0x%x",FtIn32(config_p->base_address+FXMAC_RXPAUSECNT_OFFSET)); + FXMAC_INFO("frames_rxed_64 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX64CNT_OFFSET)); + FXMAC_INFO("frames_rxed_65 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX65CNT_OFFSET)); + FXMAC_INFO("frames_rxed_128 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX128CNT_OFFSET)); + FXMAC_INFO("frames_rxed_256 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX256CNT_OFFSET)); + FXMAC_INFO("frames_rxed_512 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX512CNT_OFFSET)); + FXMAC_INFO("frames_rxed_1024 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX1024CNT_OFFSET)); + FXMAC_INFO("frames_rxed_1519 is 0x%x",FtIn32(config_p->base_address+FXMAC_RX1519CNT_OFFSET)); + FXMAC_INFO("undersize_frames is 0x%x",FtIn32(config_p->base_address+FXMAC_RXUNDRCNT_OFFSET)); + FXMAC_INFO("excessive_rx_length is 0x%x",FtIn32(config_p->base_address+FXMAC_RXOVRCNT_OFFSET)); + FXMAC_INFO("rx_jabbers is 0x%x",FtIn32(config_p->base_address+FXMAC_RXJABCNT_OFFSET)); + FXMAC_INFO("fcs_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXFCSCNT_OFFSET)); + FXMAC_INFO("rx_length_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXLENGTHCNT_OFFSET)); + FXMAC_INFO("rx_symbol_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXSYMBCNT_OFFSET)); + FXMAC_INFO("alignment_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXALIGNCNT_OFFSET)); + FXMAC_INFO("rx_resource_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXRESERRCNT_OFFSET)); + FXMAC_INFO("rx_overruns is 0x%x",FtIn32(config_p->base_address+FXMAC_RXORCNT_OFFSET)); + FXMAC_INFO("rx_ip_ck_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXIPCCNT_OFFSET)); + FXMAC_INFO("rx_tcp_ck_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXTCPCCNT_OFFSET)); + FXMAC_INFO("rx_udp_ck_errors is 0x%x",FtIn32(config_p->base_address+FXMAC_RXUDPCCNT_OFFSET)); +} + + +void FXmacDebugUsxPrint(FXmac *instance_p) +{ + FXmacConfig *config_p; + config_p = &instance_p->config; + + FXMAC_INFO("USXGMII control register is 0x%x",FtIn32(config_p->base_address+FXMAC_GEM_USX_CONTROL_OFFSET)); + FXMAC_INFO("USXGMII Status Register is 0x%x",FtIn32(config_p->base_address+FXMAC_GEM_USX_STATUS_OFFSET)); +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_g.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_g.c index b8f1b053f3..dfe1b9ce26 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_g.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_g.c @@ -14,11 +14,12 @@ * FilePath: fxmac_g.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file provide a template for user to define their own hardware settings. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac.h" @@ -36,117 +37,132 @@ * The configuration table for emacps device */ -const FXmacConfig fxmac_cfg_tbl[FT_XMAC_NUM] = +const FXmacConfig fxmac_cfg_tbl[FXMAC_NUM] = { - [FT_XMAC0_ID] = + [FXMAC0_ID] = { - .instance_id = (u32)FT_XMAC0_ID, /* Device ID */ - .base_address = (uintptr)FT_XMAC0_BASEADDRESS, /* Device base address */ - .extral_mode_base = FT_XMAC0_MODE_SEL_BASEADDRESS, - .extral_loopback_base = FT_XMAC0_LOOPBACK_SEL_BASEADDRESS, + .instance_id = (u32)FXMAC0_ID, /* Device ID */ + .base_address = (uintptr)FXMAC0_BASE_ADDR, /* Device base address */ +#if defined(FXMAC0_MODE_SEL_BASE_ADDR) + .extral_mode_base = FXMAC0_MODE_SEL_BASE_ADDR, +#endif +#if defined(FXMAC0_LOOPBACK_SEL_BASE_ADDR) + .extral_loopback_base = FXMAC0_LOOPBACK_SEL_BASE_ADDR, +#endif .interface = FXMAC_PHY_INTERFACE_MODE_SGMII, .speed = 1000, .duplex = 1, .auto_neg = 1, - .pclk_hz = FT_XMAC0_PCLK, + .pclk_hz = FXMAC0_PCLK, .max_queue_num = 16, .tx_queue_id = 0, .rx_queue_id = 0, - .hotplug_irq_num = FT_XMAC0_HOTPLUG_IRQ_NUM, +#ifdef FXMAC0_HOTPLUG_IRQ_NUM + .hotplug_irq_num = FXMAC0_HOTPLUG_IRQ_NUM, +#endif .dma_brust_length = 16, .network_default_config = FXMAC_DEFAULT_OPTIONS, .queue_irq_num = { - FT_XMAC0_QUEUE0_IRQ_NUM, - FT_XMAC0_QUEUE1_IRQ_NUM, - FT_XMAC0_QUEUE2_IRQ_NUM, - FT_XMAC0_QUEUE3_IRQ_NUM, - FT_XMAC0_QUEUE4_IRQ_NUM, - FT_XMAC0_QUEUE5_IRQ_NUM, - FT_XMAC0_QUEUE6_IRQ_NUM, - FT_XMAC0_QUEUE7_IRQ_NUM + FXMAC0_QUEUE0_IRQ_NUM, + FXMAC0_QUEUE1_IRQ_NUM, + FXMAC0_QUEUE2_IRQ_NUM, + FXMAC0_QUEUE3_IRQ_NUM, +#if defined(FXMAC0_QUEUE4_IRQ_NUM) + FXMAC0_QUEUE4_IRQ_NUM, +#endif +#if defined(FXMAC0_QUEUE5_IRQ_NUM) + FXMAC0_QUEUE5_IRQ_NUM, +#endif +#if defined(FXMAC0_QUEUE6_IRQ_NUM) + FXMAC0_QUEUE6_IRQ_NUM, +#endif +#if defined(FXMAC0_QUEUE7_IRQ_NUM) + FXMAC0_QUEUE7_IRQ_NUM +#endif } }, -#ifdef FT_XMAC1_ID - [FT_XMAC1_ID] = +#ifdef FXMAC1_ID + [FXMAC1_ID] = { - .instance_id = (u32)FT_XMAC1_ID, /* Device ID */ - .base_address = (uintptr)FT_XMAC1_BASEADDRESS, /* Device base address */ - .extral_mode_base = FT_XMAC1_MODE_SEL_BASEADDRESS, - .extral_loopback_base = FT_XMAC1_LOOPBACK_SEL_BASEADDRESS, + .instance_id = (u32)FXMAC1_ID, /* Device ID */ + .base_address = (uintptr)FXMAC1_BASE_ADDR, /* Device base address */ + .extral_mode_base = FXMAC1_MODE_SEL_BASE_ADDR, + .extral_loopback_base = FXMAC1_LOOPBACK_SEL_BASE_ADDR, .interface = FXMAC_PHY_INTERFACE_MODE_SGMII, .speed = 1000, .duplex = 1, .auto_neg = 1, - .pclk_hz = FT_XMAC1_PCLK, + .pclk_hz = FXMAC1_PCLK, .max_queue_num = 4, .tx_queue_id = 0, .rx_queue_id = 0, - .hotplug_irq_num = FT_XMAC1_HOTPLUG_IRQ_NUM, +#if defined(FXMAC1_HOTPLUG_IRQ_NUM) + .hotplug_irq_num = FXMAC1_HOTPLUG_IRQ_NUM, +#endif .dma_brust_length = 16, .network_default_config = FXMAC_DEFAULT_OPTIONS, .queue_irq_num = { - FT_XMAC1_QUEUE0_IRQ_NUM, - FT_XMAC1_QUEUE1_IRQ_NUM, - FT_XMAC1_QUEUE2_IRQ_NUM, - FT_XMAC1_QUEUE3_IRQ_NUM + FXMAC1_QUEUE0_IRQ_NUM, + FXMAC1_QUEUE1_IRQ_NUM, + FXMAC1_QUEUE2_IRQ_NUM, + FXMAC1_QUEUE3_IRQ_NUM } }, #endif -#ifdef FT_XMAC2_ID - [FT_XMAC2_ID] = +#ifdef FXMAC2_ID + [FXMAC2_ID] = { - .instance_id = (u32)FT_XMAC2_ID, /* Device ID */ - .base_address = (uintptr)FT_XMAC2_BASEADDRESS, /* Device base address */ - .extral_mode_base = FT_XMAC2_MODE_SEL_BASEADDRESS, - .extral_loopback_base = FT_XMAC2_LOOPBACK_SEL_BASEADDRESS, + .instance_id = (u32)FXMAC2_ID, /* Device ID */ + .base_address = (uintptr)FXMAC2_BASE_ADDR, /* Device base address */ + .extral_mode_base = FXMAC2_MODE_SEL_BASE_ADDR, + .extral_loopback_base = FXMAC2_LOOPBACK_SEL_BASE_ADDR, .interface = FXMAC_PHY_INTERFACE_MODE_RGMII, .speed = 1000, .duplex = 1, .auto_neg = 1, - .pclk_hz = FT_XMAC2_PCLK, + .pclk_hz = FXMAC2_PCLK, .max_queue_num = 4, .tx_queue_id = 0, .rx_queue_id = 0, - .hotplug_irq_num = FT_XMAC2_HOTPLUG_IRQ_NUM, + .hotplug_irq_num = FXMAC2_HOTPLUG_IRQ_NUM, .dma_brust_length = 16, .network_default_config = FXMAC_DEFAULT_OPTIONS, .queue_irq_num = { - FT_XMAC2_QUEUE0_IRQ_NUM, - FT_XMAC2_QUEUE1_IRQ_NUM, - FT_XMAC2_QUEUE2_IRQ_NUM, - FT_XMAC2_QUEUE3_IRQ_NUM + FXMAC2_QUEUE0_IRQ_NUM, + FXMAC2_QUEUE1_IRQ_NUM, + FXMAC2_QUEUE2_IRQ_NUM, + FXMAC2_QUEUE3_IRQ_NUM } }, #endif -#ifdef FT_XMAC3_ID - [FT_XMAC3_ID] = +#ifdef FXMAC3_ID + [FXMAC3_ID] = { - .instance_id = (u32)FT_XMAC3_ID, /* Device ID */ - .base_address = (uintptr)FT_XMAC3_BASEADDRESS, /* Device base address */ - .extral_mode_base = FT_XMAC3_MODE_SEL_BASEADDRESS, - .extral_loopback_base = FT_XMAC3_LOOPBACK_SEL_BASEADDRESS, + .instance_id = (u32)FXMAC3_ID, /* Device ID */ + .base_address = (uintptr)FXMAC3_BASE_ADDR, /* Device base address */ + .extral_mode_base = FXMAC3_MODE_SEL_BASE_ADDR, + .extral_loopback_base = FXMAC3_LOOPBACK_SEL_BASE_ADDR, .interface = FXMAC_PHY_INTERFACE_MODE_RGMII, .speed = 1000, .duplex = 1, .auto_neg = 1, - .pclk_hz = FT_XMAC3_PCLK, + .pclk_hz = FXMAC3_PCLK, .max_queue_num = 4, .tx_queue_id = 0, .rx_queue_id = 0, - .hotplug_irq_num = FT_XMAC3_HOTPLUG_IRQ_NUM, + .hotplug_irq_num = FXMAC3_HOTPLUG_IRQ_NUM, .dma_brust_length = 16, .network_default_config = FXMAC_DEFAULT_OPTIONS, .queue_irq_num = { - FT_XMAC3_QUEUE0_IRQ_NUM, - FT_XMAC3_QUEUE1_IRQ_NUM, - FT_XMAC3_QUEUE2_IRQ_NUM, - FT_XMAC3_QUEUE3_IRQ_NUM + FXMAC3_QUEUE0_IRQ_NUM, + FXMAC3_QUEUE1_IRQ_NUM, + FXMAC3_QUEUE2_IRQ_NUM, + FXMAC3_QUEUE3_IRQ_NUM } } #endif }; -/** @} */ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_hw.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_hw.h index f3814bd897..0df7a81f6b 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_hw.h @@ -14,32 +14,31 @@ * FilePath: fxmac_hw.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is hardware definition file. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef BSP_DRIVERS_ETH_FMAC_HW_H -#define BSP_DRIVERS_ETH_FMAC_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FXMAC_HW_H +#define FXMAC_HW_H #include "fparameters.h" #include "fio.h" #include "ftypes.h" #include "fkernel.h" -#define FXMAC_RX_BUF_SIZE 1536U /* Specify the receive buffer size in \ - bytes, 64, 128, ... 10240 */ +#ifdef __cplusplus +extern "C" +{ +#endif + +#define FXMAC_RX_BUF_SIZE 1536U /* Specify the receive buffer size in bytes, 64, 128, ... 10240 */ #define FXMAC_RX_BUF_SIZE_JUMBO 10240U -#define FXMAC_RX_BUF_UNIT 64U /* Number of receive buffer bytes as a \ - unit, this is HW setup */ +#define FXMAC_RX_BUF_UNIT 64U /* Number of receive buffer bytes as a unit, this is HW setup */ #define FXMAC_MAX_RXBD 128U /* Size of RX buffer descriptor queues */ #define FXMAC_MAX_TXBD 128U /* Size of TX buffer descriptor queues */ @@ -48,22 +47,17 @@ extern "C" /************************** Constant Definitions *****************************/ -#define FXMAC_MAX_MAC_ADDR 4U /* Maxmum number of mac address \ - supported */ +#define FXMAC_MAX_MAC_ADDR 4U /* Maxmum number of mac address supported */ #define FXMAC_MAX_TYPE_ID 4U /* Maxmum number of type id supported */ #ifdef __aarch64__ -#define FXMAC_BD_ALIGNMENT 64U /* Minimum buffer descriptor alignment \ - on the local bus */ +#define FXMAC_BD_ALIGNMENT 64U /* Minimum buffer descriptor alignment on the local bus */ #else -#define FXMAC_BD_ALIGNMENT 4U /* Minimum buffer descriptor alignment \ - on the local bus */ +#define FXMAC_BD_ALIGNMENT 4U /* Minimum buffer descriptor alignment on the local bus */ #endif -#define FXMAC_RX_BUF_ALIGNMENT 4U /* Minimum buffer alignment when using \ - options that impose alignment \ - restrictions on the buffer data on \ - the local bus */ +#define FXMAC_RX_BUF_ALIGNMENT 4U /* Minimum buffer alignment when using options that impose + alignment restrictions on the buffer data on the local bus */ #define FXMAC_NWCTRL_OFFSET 0x00000000U /* Network Control reg */ #define FXMAC_NWCFG_OFFSET 0x00000004U /* Network Config reg */ @@ -107,128 +101,69 @@ extern "C" #define FXMAC_STRETCH_OFFSET 0x000000BCU /* IPG Stretch reg */ #define FXMAC_REVISION_REG_OFFSET 0x000000FCU /* identification number and module revision */ -#define FXMAC_OCTTXL_OFFSET 0x00000100U /* Octects transmitted Low \ - reg */ -#define FXMAC_OCTTXH_OFFSET 0x00000104U /* Octects transmitted High \ - reg */ +#define FXMAC_OCTTXL_OFFSET 0x00000100U /* Octects transmitted Low reg */ +#define FXMAC_OCTTXH_OFFSET 0x00000104U /* Octects transmitted High reg */ -#define FXMAC_TXCNT_OFFSET 0x00000108U /* Error-free Frmaes \ - transmitted counter */ -#define FXMAC_TXBCCNT_OFFSET 0x0000010CU /* Error-free Broadcast \ - Frames counter*/ -#define FXMAC_TXMCCNT_OFFSET 0x00000110U /* Error-free Multicast \ - Frame counter */ -#define FXMAC_TXPAUSECNT_OFFSET 0x00000114U /* Pause Frames Transmitted \ - Counter */ -#define FXMAC_TX64CNT_OFFSET 0x00000118U /* Error-free 64 byte Frames \ - Transmitted counter */ -#define FXMAC_TX65CNT_OFFSET 0x0000011CU /* Error-free 65-127 byte \ - Frames Transmitted \ - counter */ -#define FXMAC_TX128CNT_OFFSET 0x00000120U /* Error-free 128-255 byte \ - Frames Transmitted \ - counter*/ -#define FXMAC_TX256CNT_OFFSET 0x00000124U /* Error-free 256-511 byte \ - Frames transmitted \ - counter */ -#define FXMAC_TX512CNT_OFFSET 0x00000128U /* Error-free 512-1023 byte \ - Frames transmitted \ - counter */ -#define FXMAC_TX1024CNT_OFFSET 0x0000012CU /* Error-free 1024-1518 byte \ - Frames transmitted \ - counter */ -#define FXMAC_TX1519CNT_OFFSET 0x00000130U /* Error-free larger than \ - 1519 byte Frames \ - transmitted counter */ -#define FXMAC_TXURUNCNT_OFFSET 0x00000134U /* TX under run error \ - counter */ +#define FXMAC_TXCNT_OFFSET 0x00000108U /* Error-free Frmaes transmitted counter */ +#define FXMAC_TXBCCNT_OFFSET 0x0000010CU /* Error-free Broadcast Frames counter*/ +#define FXMAC_TXMCCNT_OFFSET 0x00000110U /* Error-free Multicast Frame counter */ +#define FXMAC_TXPAUSECNT_OFFSET 0x00000114U /* Pause Frames Transmitted Counter */ +#define FXMAC_TX64CNT_OFFSET 0x00000118U /* Error-free 64 byte Frames Transmitted counter */ +#define FXMAC_TX65CNT_OFFSET 0x0000011CU /* Error-free 65-127 byte Frames Transmitted counter */ +#define FXMAC_TX128CNT_OFFSET 0x00000120U /* Error-free 128-255 byte Frames Transmitted counter*/ +#define FXMAC_TX256CNT_OFFSET 0x00000124U /* Error-free 256-511 byte Frames transmitted counter */ +#define FXMAC_TX512CNT_OFFSET 0x00000128U /* Error-free 512-1023 byte Frames transmitted counter */ +#define FXMAC_TX1024CNT_OFFSET 0x0000012CU /* Error-free 1024-1518 byte Frames transmitted counter */ +#define FXMAC_TX1519CNT_OFFSET 0x00000130U /* Error-free larger than 1519 byte Frames transmitted counter */ +#define FXMAC_TXURUNCNT_OFFSET 0x00000134U /* TX under run error counter */ -#define FXMAC_SNGLCOLLCNT_OFFSET 0x00000138U /* Single Collision Frame \ - Counter */ -#define FXMAC_MULTICOLLCNT_OFFSET 0x0000013CU /* Multiple Collision Frame \ - Counter */ -#define FXMAC_EXCESSCOLLCNT_OFFSET 0x00000140U /* Excessive Collision Frame \ - Counter */ -#define FXMAC_LATECOLLCNT_OFFSET 0x00000144U /* Late Collision Frame \ - Counter */ -#define FXMAC_TXDEFERCNT_OFFSET 0x00000148U /* Deferred Transmission \ - Frame Counter */ -#define FXMAC_TXCSENSECNT_OFFSET 0x0000014CU /* Transmit Carrier Sense \ - Error Counter */ +#define FXMAC_SNGLCOLLCNT_OFFSET 0x00000138U /* Single Collision Frame Counter */ +#define FXMAC_MULTICOLLCNT_OFFSET 0x0000013CU /* Multiple Collision Frame Counter */ +#define FXMAC_EXCESSCOLLCNT_OFFSET 0x00000140U /* Excessive Collision Frame Counter */ +#define FXMAC_LATECOLLCNT_OFFSET 0x00000144U /* Late Collision Frame Counter */ +#define FXMAC_TXDEFERCNT_OFFSET 0x00000148U /* Deferred Transmission Frame Counter */ +#define FXMAC_TXCSENSECNT_OFFSET 0x0000014CU /* Transmit Carrier Sense Error Counter */ -#define FXMAC_OCTRXL_OFFSET 0x00000150U /* Octects Received register \ - Low */ -#define FXMAC_OCTRXH_OFFSET 0x00000154U /* Octects Received register \ - High */ +#define FXMAC_OCTRXL_OFFSET 0x00000150U /* Octects Received register Low */ +#define FXMAC_OCTRXH_OFFSET 0x00000154U /* Octects Received register High */ -#define FXMAC_RXCNT_OFFSET 0x00000158U /* Error-free Frames \ - Received Counter */ -#define FXMAC_RXBROADCNT_OFFSET 0x0000015CU /* Error-free Broadcast \ - Frames Received Counter */ -#define FXMAC_RXMULTICNT_OFFSET 0x00000160U /* Error-free Multicast \ - Frames Received Counter */ -#define FXMAC_RXPAUSECNT_OFFSET 0x00000164U /* Pause Frames \ - Received Counter */ -#define FXMAC_RX64CNT_OFFSET 0x00000168U /* Error-free 64 byte Frames \ - Received Counter */ -#define FXMAC_RX65CNT_OFFSET 0x0000016CU /* Error-free 65-127 byte \ - Frames Received Counter */ -#define FXMAC_RX128CNT_OFFSET 0x00000170U /* Error-free 128-255 byte \ - Frames Received Counter */ -#define FXMAC_RX256CNT_OFFSET 0x00000174U /* Error-free 256-512 byte \ - Frames Received Counter */ -#define FXMAC_RX512CNT_OFFSET 0x00000178U /* Error-free 512-1023 byte \ - Frames Received Counter */ -#define FXMAC_RX1024CNT_OFFSET 0x0000017CU /* Error-free 1024-1518 byte \ - Frames Received Counter */ -#define FXMAC_RX1519CNT_OFFSET 0x00000180U /* Error-free 1519-max byte \ - Frames Received Counter */ -#define FXMAC_RXUNDRCNT_OFFSET 0x00000184U /* Undersize Frames Received \ - Counter */ -#define FXMAC_RXOVRCNT_OFFSET 0x00000188U /* Oversize Frames Received \ - Counter */ -#define FXMAC_RXJABCNT_OFFSET 0x0000018CU /* Jabbers Received \ - Counter */ -#define FXMAC_RXFCSCNT_OFFSET 0x00000190U /* Frame Check Sequence \ - Error Counter */ -#define FXMAC_RXLENGTHCNT_OFFSET 0x00000194U /* Length Field Error \ - Counter */ +#define FXMAC_RXCNT_OFFSET 0x00000158U /* Error-free Frames Received Counter */ +#define FXMAC_RXBROADCNT_OFFSET 0x0000015CU /* Error-free Broadcast Frames Received Counter */ +#define FXMAC_RXMULTICNT_OFFSET 0x00000160U /* Error-free Multicast Frames Received Counter */ +#define FXMAC_RXPAUSECNT_OFFSET 0x00000164U /* Pause Frames Received Counter */ +#define FXMAC_RX64CNT_OFFSET 0x00000168U /* Error-free 64 byte Frames Received Counter */ +#define FXMAC_RX65CNT_OFFSET 0x0000016CU /* Error-free 65-127 byte Frames Received Counter */ +#define FXMAC_RX128CNT_OFFSET 0x00000170U /* Error-free 128-255 byte Frames Received Counter */ +#define FXMAC_RX256CNT_OFFSET 0x00000174U /* Error-free 256-512 byte Frames Received Counter */ +#define FXMAC_RX512CNT_OFFSET 0x00000178U /* Error-free 512-1023 byte Frames Received Counter */ +#define FXMAC_RX1024CNT_OFFSET 0x0000017CU /* Error-free 1024-1518 byte Frames Received Counter */ +#define FXMAC_RX1519CNT_OFFSET 0x00000180U /* Error-free 1519-max byte Frames Received Counter */ +#define FXMAC_RXUNDRCNT_OFFSET 0x00000184U /* Undersize Frames Received Counter */ +#define FXMAC_RXOVRCNT_OFFSET 0x00000188U /* Oversize Frames Received Counter */ +#define FXMAC_RXJABCNT_OFFSET 0x0000018CU /* Jabbers Received Counter */ +#define FXMAC_RXFCSCNT_OFFSET 0x00000190U /* Frame Check Sequence Error Counter */ +#define FXMAC_RXLENGTHCNT_OFFSET 0x00000194U /* Length Field Error Counter */ #define FXMAC_RXSYMBCNT_OFFSET 0x00000198U /* Symbol Error Counter */ #define FXMAC_RXALIGNCNT_OFFSET 0x0000019CU /* Alignment Error Counter */ -#define FXMAC_RXRESERRCNT_OFFSET 0x000001A0U /* Receive Resource Error \ - Counter */ +#define FXMAC_RXRESERRCNT_OFFSET 0x000001A0U /* Receive Resource Error Counter */ #define FXMAC_RXORCNT_OFFSET 0x000001A4U /* Receive Overrun Counter */ -#define FXMAC_RXIPCCNT_OFFSET 0x000001A8U /* IP header Checksum Error \ - Counter */ -#define FXMAC_RXTCPCCNT_OFFSET 0x000001ACU /* TCP Checksum Error \ - Counter */ -#define FXMAC_RXUDPCCNT_OFFSET 0x000001B0U /* UDP Checksum Error \ - Counter */ -#define FXMAC_LAST_OFFSET 0x000001B4U /* Last statistic counter \ - offset, for clearing */ +#define FXMAC_RXIPCCNT_OFFSET 0x000001A8U /* IP header Checksum Error Counter */ +#define FXMAC_RXTCPCCNT_OFFSET 0x000001ACU /* TCP Checksum Error Counter */ +#define FXMAC_RXUDPCCNT_OFFSET 0x000001B0U /* UDP Checksum Error Counter */ +#define FXMAC_LAST_OFFSET 0x000001B4U /* Last statistic counter offset, for clearing */ #define FXMAC_1588_SEC_OFFSET 0x000001D0U /* 1588 second counter */ #define FXMAC_1588_NANOSEC_OFFSET 0x000001D4U /* 1588 nanosecond counter */ -#define FXMAC_1588_ADJ_OFFSET 0x000001D8U /* 1588 nanosecond \ - adjustment counter */ -#define FXMAC_1588_INC_OFFSET 0x000001DCU /* 1588 nanosecond \ - increment counter */ -#define FXMAC_PTP_TXSEC_OFFSET 0x000001E0U /* 1588 PTP transmit second \ - counter */ -#define FXMAC_PTP_TXNANOSEC_OFFSET 0x000001E4U /* 1588 PTP transmit \ - nanosecond counter */ -#define FXMAC_PTP_RXSEC_OFFSET 0x000001E8U /* 1588 PTP receive second \ - counter */ -#define FXMAC_PTP_RXNANOSEC_OFFSET 0x000001ECU /* 1588 PTP receive \ - nanosecond counter */ -#define FXMAC_PTPP_TXSEC_OFFSET 0x000001F0U /* 1588 PTP peer transmit \ - second counter */ -#define FXMAC_PTPP_TXNANOSEC_OFFSET 0x000001F4U /* 1588 PTP peer transmit \ - nanosecond counter */ -#define FXMAC_PTPP_RXSEC_OFFSET 0x000001F8U /* 1588 PTP peer receive \ - second counter */ -#define FXMAC_PTPP_RXNANOSEC_OFFSET 0x000001FCU /* 1588 PTP peer receive \ - nanosecond counter */ +#define FXMAC_1588_ADJ_OFFSET 0x000001D8U /* 1588 nanosecond adjustment counter */ +#define FXMAC_1588_INC_OFFSET 0x000001DCU /* 1588 nanosecond increment counter */ +#define FXMAC_PTP_TXSEC_OFFSET 0x000001E0U /* 1588 PTP transmit second counter */ +#define FXMAC_PTP_TXNANOSEC_OFFSET 0x000001E4U /* 1588 PTP transmit nanosecond counter */ +#define FXMAC_PTP_RXSEC_OFFSET 0x000001E8U /* 1588 PTP receive second counter */ +#define FXMAC_PTP_RXNANOSEC_OFFSET 0x000001ECU /* 1588 PTP receive nanosecond counter */ +#define FXMAC_PTPP_TXSEC_OFFSET 0x000001F0U /* 1588 PTP peer transmit second counter */ +#define FXMAC_PTPP_TXNANOSEC_OFFSET 0x000001F4U /* 1588 PTP peer transmit nanosecond counter */ +#define FXMAC_PTPP_RXSEC_OFFSET 0x000001F8U /* 1588 PTP peer receive second counter */ +#define FXMAC_PTPP_RXNANOSEC_OFFSET 0x000001FCU /* 1588 PTP peer receive nanosecond counter */ #define FXMAC_PCS_CONTROL_OFFSET 0x00000200U /* All PCS registers */ @@ -242,29 +177,26 @@ extern "C" #define FXMAC_INTQ1_STS_OFFSET 0x00000400U /* Interrupt Q1 Status reg */ -#define FXMAC_TXQ1BASE_OFFSET 0x00000440U /* TX Q1 Base address \ - reg */ -#define FXMAC_RXQ1BASE_OFFSET 0x00000480U /* RX Q1 Base address \ - reg */ +#define FXMAC_TXQ1BASE_OFFSET 0x00000440U /* TX Q1 Base address reg */ +#define FXMAC_RXQ1BASE_OFFSET 0x00000480U /* RX Q1 Base address reg */ #define FXMAC_RXBUFQ1_SIZE_OFFSET 0x000004a0U /* Receive Buffer Size */ #define FXMAC_RXBUFQX_SIZE_OFFSET(x) (FXMAC_RXBUFQ1_SIZE_OFFSET + (x << 2)) #define FXMAC_RXBUFQX_SIZE_MASK GENMASK(7, 0) #define FXMAC_MSBBUF_TXQBASE_OFFSET 0x000004C8U /* MSB Buffer TX Q Base reg */ -#define FXMAC_MSBBUF_RXQBASE_OFFSET 0x000004D4U /* MSB Buffer RX Q Base \ - reg */ +#define FXMAC_MSBBUF_RXQBASE_OFFSET 0x000004D4U /* MSB Buffer RX Q Base reg */ #define FXMAC_INTQ1_IER_OFFSET 0x00000600U /* Interrupt Q1 Enable reg */ #define FXMAC_INTQX_IER_SIZE_OFFSET(x) (FXMAC_INTQ1_IER_OFFSET + (x << 2)) #define FXMAC_INTQ1_IDR_OFFSET 0x00000620U /* Interrupt Q1 Disable reg */ #define FXMAC_INTQX_IDR_SIZE_OFFSET(x) (FXMAC_INTQ1_IDR_OFFSET + (x << 2)) -#define FXMAC_INTQ1_IMR_OFFSET 0x00000640U /* Interrupt Q1 Mask \ - reg */ +#define FXMAC_INTQ1_IMR_OFFSET 0x00000640U /* Interrupt Q1 Mask reg */ #define FXMAC_GEM_USX_CONTROL_OFFSET 0x0A80 /* High speed PCS control register */ #define FXMAC_TEST_CONTROL_OFFSET 0X0A84 /* USXGMII Test Control Register */ +#define FXMAC_GEM_USX_STATUS_OFFSET 0x0A88 /* USXGMII Status Register */ #define FXMAC_GEM_SRC_SEL_LN 0x1C04 #define FXMAC_GEM_DIV_SEL0_LN 0x1C08 @@ -316,8 +248,7 @@ extern "C" #define FXMAC_IXR_RXOVR_MASK BIT(10) /* Receive overrun occurred */ #define FXMAC_IXR_LINKCHANGE_MASK BIT(9) /* link status change */ #define FXMAC_IXR_TXCOMPL_MASK BIT(7) /* Frame transmitted ok */ -#define FXMAC_IXR_TXEXH_MASK BIT(6) /* Transmit err occurred or \ - no buffers*/ +#define FXMAC_IXR_TXEXH_MASK BIT(6) /* Transmit err occurred or no buffers*/ #define FXMAC_IXR_RETRY_MASK BIT(5) /* Retry limit exceeded */ #define FXMAC_IXR_URUN_MASK BIT(4) /* Transmit underrun */ #define FXMAC_IXR_TXUSED_MASK BIT(3) /* Tx buffer used bit read */ @@ -341,21 +272,15 @@ extern "C" #define FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK BIT(29) /* 2.5G operation selected */ -#define FXMAC_NWCTRL_FLUSH_DPRAM_MASK BIT(18) /* Flush a packet from \ - Rx SRAM */ -#define FXMAC_NWCTRL_ZEROPAUSETX_MASK BIT(11) /* Transmit zero quantum \ - pause frame */ +#define FXMAC_NWCTRL_FLUSH_DPRAM_MASK BIT(18) /* Flush a packet from Rx SRAM */ +#define FXMAC_NWCTRL_ZEROPAUSETX_MASK BIT(11) /* Transmit zero quantum pause frame */ #define FXMAC_NWCTRL_PAUSETX_MASK BIT(11) /* Transmit pause frame */ -#define FXMAC_NWCTRL_HALTTX_MASK BIT(10) /* Halt transmission \ - after current frame */ +#define FXMAC_NWCTRL_HALTTX_MASK BIT(10) /* Halt transmission after current frame */ #define FXMAC_NWCTRL_STARTTX_MASK BIT(9) /* Start tx (tx_go) */ -#define FXMAC_NWCTRL_STATWEN_MASK BIT(7) /* Enable writing to \ - stat counters */ -#define FXMAC_NWCTRL_STATINC_MASK BIT(6) /* Increment statistic \ - registers */ -#define FXMAC_NWCTRL_STATCLR_MASK BIT(5) /* Clear statistic \ - registers */ +#define FXMAC_NWCTRL_STATWEN_MASK BIT(7) /* Enable writing to stat counters */ +#define FXMAC_NWCTRL_STATINC_MASK BIT(6) /* Increment statistic registers */ +#define FXMAC_NWCTRL_STATCLR_MASK BIT(5) /* Clear statistic registers */ #define FXMAC_NWCTRL_MDEN_MASK BIT(4) /* Enable MDIO port */ #define FXMAC_NWCTRL_TXEN_MASK BIT(3) /* Enable transmit */ #define FXMAC_NWCTRL_RXEN_MASK BIT(2) /* Enable receive */ @@ -379,21 +304,17 @@ extern "C" #define FXMAC_NWCFG_CLOCK_DIV8_MASK (0U << 18) #define FXMAC_NWCFG_FCS_REMOVE BIT(17) /* FCS remove - setting this bit will cause received frames to be written to memory without their frame check sequence (last 4 bytes). */ +#define FXMAC_NWCFG_LENGTH_FIELD_ERROR_FRAME_DISCARD BIT(16) #define FXMAC_NWCFG_PAUSE_ENABLE BIT(13) /* Pause enable - when set, transmission will pause if a non-zero 802.3 classic pause frame is received and PFC has not been negotiated. */ #define FXMAC_NWCFG_PCSSEL_MASK BIT(11) /* PCS Select */ #define FXMAC_NWCFG_1000_MASK BIT(10) /* Gigabit mode enable */ -#define FXMAC_NWCFG_1536RXEN_MASK BIT(8) /* Enable 1536 byte \ - frames reception */ -#define FXMAC_NWCFG_UCASTHASHEN_MASK BIT(7) /* Receive unicast hash \ - frames */ -#define FXMAC_NWCFG_MCASTHASHEN_MASK BIT(6) /* Receive multicast hash \ - frames */ -#define FXMAC_NWCFG_BCASTDI_MASK BIT(5) /* Do not receive \ - broadcast frames */ +#define FXMAC_NWCFG_1536RXEN_MASK BIT(8) /* Enable 1536 byte frames reception */ +#define FXMAC_NWCFG_UCASTHASHEN_MASK BIT(7) /* Receive unicast hash frames */ +#define FXMAC_NWCFG_MCASTHASHEN_MASK BIT(6) /* Receive multicast hash frames */ +#define FXMAC_NWCFG_BCASTDI_MASK BIT(5) /* Do not receive broadcast frames */ #define FXMAC_NWCFG_COPYALLEN_MASK BIT(4) /* Copy all frames */ #define FXMAC_NWCFG_JUMBO_MASK BIT(3) /* Jumbo frames */ -#define FXMAC_NWCFG_NVLANDISC_MASK BIT(2) /* Receive only VLAN \ - frames */ +#define FXMAC_NWCFG_NVLANDISC_MASK BIT(2) /* Receive only VLAN frames */ #define FXMAC_NWCFG_FDEN_MASK BIT(1) /* full duplex */ #define FXMAC_NWCFG_100_MASK BIT(0) /* 100 Mbps */ #define FXMAC_NWCFG_RESET_MASK BIT(19) /* reset value */ @@ -414,7 +335,7 @@ extern "C" #define FXMAC_RXBUF_UNIHASH_MASK BIT(29) /* Unicast hashed frame */ #define FXMAC_RXBUF_EXH_MASK BIT(27) /* buffer exhausted */ #define FXMAC_RXBUF_AMATCH_MASK GENMASK(26, 25) /* Specific address \ - matched */ +matched */ #define FXMAC_RXBUF_IDFOUND_MASK BIT(24) /* Type ID matched */ #define FXMAC_RXBUF_IDMATCH_MASK GENMASK(23, 22) /* ID matched mask */ #define FXMAC_RXBUF_VLAN_MASK BIT(21) /* VLAN tagged */ @@ -430,6 +351,7 @@ extern "C" #define FXMAC_RXBUF_WRAP_MASK BIT(1) /* Wrap bit, last BD */ #define FXMAC_RXBUF_NEW_MASK BIT(0) /* Used bit.. */ #define FXMAC_RXBUF_ADD_MASK GENMASK(31, 2) /* Mask for address */ + /* * @} */ @@ -459,24 +381,18 @@ extern "C" /** @name network configuration register bit definitions * @{ */ -#define FXMAC_NWCFG_BADPREAMBEN_MASK BIT(29) /* disable rejection of \ - non-standard preamble */ +#define FXMAC_NWCFG_BADPREAMBEN_MASK BIT(29) /* disable rejection of non-standard preamble */ #define FXMAC_NWCFG_IPDSTRETCH_MASK BIT(28) /* enable transmit IPG */ #define FXMAC_NWCFG_SGMIIEN_MASK BIT(27) /* SGMII Enable */ -#define FXMAC_NWCFG_FCSIGNORE_MASK BIT(26) /* disable rejection of \ - FCS error */ +#define FXMAC_NWCFG_FCSIGNORE_MASK BIT(26) /* disable rejection of FCS error */ #define FXMAC_NWCFG_HDRXEN_MASK BIT(25) /* RX half duplex */ -#define FXMAC_NWCFG_RXCHKSUMEN_MASK BIT(24) /* enable RX checksum \ - offload */ -#define FXMAC_NWCFG_PAUSECOPYDI_MASK BIT(23) /* Do not copy pause \ - Frames to memory */ +#define FXMAC_NWCFG_RXCHKSUMEN_MASK BIT(24) /* enable RX checksum offload */ +#define FXMAC_NWCFG_PAUSECOPYDI_MASK BIT(23) /* Do not copy pause Frames to memory */ #define FXMAC_NWCFG_DWIDTH_64_MASK BIT(21) /* 64 bit Data bus width */ #define FXMAC_NWCFG_MDC_SHIFT_MASK 18U /* shift bits for MDC */ #define FXMAC_NWCFG_MDCCLKDIV_MASK GENMASK(20, 18) /* MDC Mask PCLK divisor */ -#define FXMAC_NWCFG_FCSREM_MASK BIT(17) /* Discard FCS from \ - received frames */ -#define FXMAC_NWCFG_LENERRDSCRD_MASK BIT(16) -/* RX length error discard */ +#define FXMAC_NWCFG_FCSREM_MASK BIT(17) /* Discard FCS from received frames */ +#define FXMAC_NWCFG_LENERRDSCRD_MASK BIT(16) /* RX length error discard */ #define FXMAC_NWCFG_RXOFFS_MASK GENMASK(15) /* RX buffer offset */ #define FXMAC_NWCFG_PAUSEEN_MASK BIT(13) /* Enable pause RX */ #define FXMAC_NWCFG_RETRYTESTEN_MASK BIT(12) /* Retry test */ @@ -507,12 +423,9 @@ extern "C" #define FXMAC_DMACR_TXEXTEND_MASK BIT(29) /* Tx Extended desc mode */ #define FXMAC_DMACR_RXEXTEND_MASK BIT(28) /* Rx Extended desc mode */ #define FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK BIT(24) /* Auto Discard RX frames during lack of resource. */ -#define FXMAC_DMACR_RXBUF_MASK GENMASK(23, 16) /* Mask bit for RX buffer \ - size */ -#define FXMAC_DMACR_RXBUF_SHIFT 16U /* Shift bit for RX buffer \ - size */ -#define FXMAC_DMACR_TCPCKSUM_MASK BIT(11) /* enable/disable TX \ - checksum offload */ +#define FXMAC_DMACR_RXBUF_MASK GENMASK(23, 16) /* Mask bit for RX buffer size */ +#define FXMAC_DMACR_RXBUF_SHIFT 16U /* Shift bit for RX buffer size */ +#define FXMAC_DMACR_TCPCKSUM_MASK BIT(11) /* enable/disable TX checksum offload */ #define FXMAC_DMACR_TXSIZE_MASK BIT(10) /* TX buffer memory size bit[10] */ #define FXMAC_DMACR_RXSIZE_MASK GENMASK(9, 8) /* RX buffer memory size bit[9:8] */ #define FXMAC_DMACR_ENDIAN_MASK BIT(7) /* endian configuration */ @@ -554,8 +467,7 @@ extern "C" #define FXMAC_TXSR_HRESPNOK_MASK BIT(8) /* Transmit hresp not OK */ #define FXMAC_TXSR_URUN_MASK BIT(6) /* Transmit underrun */ #define FXMAC_TXSR_TXCOMPL_MASK BIT(5) /* Transmit completed OK */ -#define FXMAC_TXSR_BUFEXH_MASK BIT(4) /* Transmit buffs exhausted \ - mid frame */ +#define FXMAC_TXSR_BUFEXH_MASK BIT(4) /* Transmit buffs exhausted mid frame */ #define FXMAC_TXSR_TXGO_MASK BIT(3) /* Status of go flag */ #define FXMAC_TXSR_RXOVR_MASK BIT(2) /* Retry limit exceeded */ #define FXMAC_TXSR_FRAMERX_MASK BIT(1) /* Collision tx frame */ @@ -595,6 +507,7 @@ extern "C" /* Design Configuration Register 1 - The GEM has many parameterisation options to configure the IP during compilation stage. */ #define FXMAC_DESIGNCFG_DEBUG1_BUS_WIDTH_MASK GENMASK(27, 25) +#define FXMAC_DESIGNCFG_DEBUG1_BUS_IRQCOR_MASK BIT(23) /*GEM hs mac config register bitfields*/ #define FXMAC_GEM_HSMACSPEED_OFFSET 0 @@ -611,14 +524,16 @@ extern "C" /** @name MAC address register word 1 mask * @{ */ -#define FXMAC_GEM_SAB_MASK GENMASK(15, 0) /* Address bits[47:32] \ - bit[31:0] are in BOTTOM */ +#define FXMAC_GEM_SAB_MASK GENMASK(15, 0) /* Address bits[47:32] bit[31:0] are in BOTTOM */ /* USXGMII control register */ #define FXMAC_GEM_USX_HS_MAC_SPEED_100M (0x0 << 14) /* 100M operation */ #define FXMAC_GEM_USX_HS_MAC_SPEED_1G (0x1 << 14) /* 1G operation */ #define FXMAC_GEM_USX_HS_MAC_SPEED_2_5G (0x2 << 14) /* 2.5G operation */ +#define FXMAC_GEM_USX_HS_MAC_SPEED_5G (0x3 << 14) /* 5G operation */ #define FXMAC_GEM_USX_HS_MAC_SPEED_10G (0x4 << 14) /* 10G operation */ +#define FXMAC_GEM_USX_SERDES_RATE_5G (0x0 << 12) +#define FXMAC_GEM_USX_SERDES_RATE_10G (0x1 << 12) #define FXMAC_GEM_USX_TX_SCR_BYPASS BIT(8) /* RX Scrambler Bypass. Set high to bypass the receive descrambler. */ #define FXMAC_GEM_USX_RX_SCR_BYPASS BIT(9) /* TX Scrambler Bypass. Set high to bypass the transmit scrambler. */ #define FXMAC_GEM_USX_RX_SYNC_RESET BIT(2) /* RX Reset. Set high to reset the receive datapath. When low the receive datapath is enabled. */ @@ -642,6 +557,12 @@ extern "C" #define FXMAC_PCS_AN_LP_DUPLEX (0x3U << FXMAC_PCS_AN_LP_DUPLEX_OFFSET) /* SGMII Bit 13: Reserved. read as 0. Bit 12 : 0 : half-duplex. 1: Full Duplex." */ #define FXMAC_PCS_LINK_PARTNER_NEXT_PAGE_STATUS (1U<<15) /* In sgmii mode, 0 is link down . 1 is link up */ + +/* USXGMII Status Register */ + +#define FXMAC_GEM_USX_STATUS_BLOCK_LOCK BIT(0) /* Block Lock. A value of one indicates that the PCS has achieved block synchronization. */ + + /***************** Macros (Inline Functions) Definitions *********************/ #define FXMAC_READREG32(addr, reg_offset) FtIn32(addr + (u32)reg_offset) diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_intr.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_intr.c index 08c226740c..63d0f66cbe 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_intr.c @@ -14,11 +14,12 @@ * FilePath: fxmac_intr.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file contains functions related to interrupt handling. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac.h" @@ -61,29 +62,29 @@ FError FXmacSetHandler(FXmac *instance_p, u32 handler_type, switch (handler_type) { - case FXMAC_HANDLER_DMASEND: - instance_p->send_irq_handler = ((FXmacIrqHandler)(void *)func_pointer); - instance_p->send_args = call_back_ref; - break; - case FXMAC_HANDLER_DMARECV: - instance_p->recv_irq_handler = ((FXmacIrqHandler)(void *)func_pointer); - instance_p->recv_args = call_back_ref; - break; - case FXMAC_HANDLER_ERROR: - instance_p->error_irq_handler = ((FXmacErrorIrqHandler)(void *)func_pointer); - instance_p->error_args = call_back_ref; - break; - case FXMAC_HANDLER_LINKCHANGE: - instance_p->link_change_handler = ((FXmacIrqHandler)(void *)func_pointer); - instance_p->link_change_args = call_back_ref; - break; - case FXMAC_HANDLER_RESTART: - instance_p->restart_handler = ((FXmacIrqHandler)(void *)func_pointer); - instance_p->restart_args = call_back_ref; - break; - default: - status = (FError)(FXMAC_ERR_INVALID_PARAM); - break; + case FXMAC_HANDLER_DMASEND: + instance_p->send_irq_handler = ((FXmacIrqHandler)(void *)func_pointer); + instance_p->send_args = call_back_ref; + break; + case FXMAC_HANDLER_DMARECV: + instance_p->recv_irq_handler = ((FXmacIrqHandler)(void *)func_pointer); + instance_p->recv_args = call_back_ref; + break; + case FXMAC_HANDLER_ERROR: + instance_p->error_irq_handler = ((FXmacErrorIrqHandler)(void *)func_pointer); + instance_p->error_args = call_back_ref; + break; + case FXMAC_HANDLER_LINKCHANGE: + instance_p->link_change_handler = ((FXmacIrqHandler)(void *)func_pointer); + instance_p->link_change_args = call_back_ref; + break; + case FXMAC_HANDLER_RESTART: + instance_p->restart_handler = ((FXmacIrqHandler)(void *)func_pointer); + instance_p->restart_args = call_back_ref; + break; + default: + status = (FError)(FXMAC_ERR_INVALID_PARAM); + break; } return status; } @@ -97,34 +98,34 @@ FError FXmacSetHandler(FXmac *instance_p, u32 handler_type, * @return {*} * @note 目前中断只支持单queue的情况 */ + void FXmacIntrHandler(s32 vector, void *args) { u32 reg_isr; u32 reg_qx_isr; u32 reg_temp; u32 reg_ctrl; - u32 tx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ - u32 rx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 tx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ + u32 rx_queue_id; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ FXmac *instance_p = (FXmac *)args; FASSERT(instance_p != NULL); FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY); tx_queue_id = instance_p->tx_bd_queue.queue_id; rx_queue_id = instance_p->rx_bd_queue.queue_id; - FASSERT((rx_queue_id < FT_XMAC_QUEUE_MAX_NUM) && (tx_queue_id < FT_XMAC_QUEUE_MAX_NUM)) + FASSERT((rx_queue_id < FXMAC_QUEUE_MAX_NUM) && (tx_queue_id < FXMAC_QUEUE_MAX_NUM)) /* This ISR will try to handle as many interrupts as it can in a single * call. However, in most of the places where the user's error handler * is called, this ISR exits because it is expected that the user will * reset the device in nearly all instances. */ + reg_isr = FXMAC_READREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET); if ((u32)vector == instance_p->config.queue_irq_num[tx_queue_id]) { if (tx_queue_id == 0) { - reg_isr = FXMAC_READREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET); - if ((reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U) { /* Clear TX status register TX complete indication but preserve @@ -141,12 +142,15 @@ void FXmacIntrHandler(s32 vector, void *args) } /* add */ - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXCOMPL_MASK); + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXCOMPL_MASK); + } } /* Transmit error conditions interrupt */ if (((reg_isr & FXMAC_IXR_TX_ERR_MASK) != 0x00000000U) && - (!(reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U)) + (!(reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U)) { /* Clear TX status register */ reg_temp = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET); @@ -156,21 +160,27 @@ void FXmacIntrHandler(s32 vector, void *args) instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND, reg_temp); } /* add */ - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TX_ERR_MASK); + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TX_ERR_MASK); + } } /* add restart */ if ((reg_isr & FXMAC_IXR_TXUSED_MASK) != 0x00000000U) { /* add */ - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXUSED_MASK); + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXUSED_MASK); + } if (instance_p->restart_handler) { instance_p->restart_handler(instance_p->restart_args); } } - + /* link chaged */ if ((reg_isr & FXMAC_IXR_LINKCHANGE_MASK) != 0x00000000U) { @@ -178,7 +188,11 @@ void FXmacIntrHandler(s32 vector, void *args) { instance_p->link_change_handler(instance_p->link_change_args); } - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_LINKCHANGE_MASK); + + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_LINKCHANGE_MASK); + } } } else /* use queue number more than 0 */ @@ -203,7 +217,7 @@ void FXmacIntrHandler(s32 vector, void *args) /* Transmit Q1 error conditions interrupt */ if (((reg_isr & FXMAC_INTQ1SR_TXERR_MASK) != 0x00000000U) && - ((reg_isr & FXMAC_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) + ((reg_isr & FXMAC_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) { /* Clear Interrupt Q1 status register */ FXMAC_WRITEREG32(instance_p->config.base_address, @@ -218,9 +232,6 @@ void FXmacIntrHandler(s32 vector, void *args) { if (rx_queue_id == 0) { - reg_isr = FXMAC_READREG32(instance_p->config.base_address, - FXMAC_ISR_OFFSET); - /* Receive complete interrupt */ if ((reg_isr & FXMAC_IXR_RXCOMPL_MASK) != 0x00000000U) { @@ -233,8 +244,10 @@ void FXmacIntrHandler(s32 vector, void *args) instance_p->recv_irq_handler(instance_p->recv_args); /* add */ - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXCOMPL_MASK); - + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXCOMPL_MASK); + } } /* Receive error conditions interrupt */ @@ -269,13 +282,19 @@ void FXmacIntrHandler(s32 vector, void *args) /* add */ if ((reg_isr & FXMAC_IXR_RXOVR_MASK) != 0x00000000U) { - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXOVR_MASK); + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXOVR_MASK); + } } /* add */ if ((reg_isr & FXMAC_IXR_HRESPNOK_MASK) != 0x00000000U) { - FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_HRESPNOK_MASK); + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_HRESPNOK_MASK); + } } if (reg_temp != 0) @@ -348,7 +367,6 @@ void FXmacIntrHandler(s32 vector, void *args) } } } - } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_options.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_options.c index c4e4b0d570..1d05fef097 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_options.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_options.c @@ -14,16 +14,18 @@ * FilePath: fxmac_options.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for options functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac_hw.h" #include "fxmac.h" #include "fassert.h" +#include "ftypes.h" /** @@ -637,7 +639,7 @@ FError FXmacPhyWrite(FXmac *instance_p, u32 phy_address, /* Make sure no other PHY operation is currently in progress */ if ((!(FXMAC_READREG32(instance_p->config.base_address, FXMAC_NWSR_OFFSET) & - FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE) + FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE) { status = (FError)(FXMAC_ERR_PHY_BUSY); } @@ -713,7 +715,7 @@ FError FXmacPhyRead(FXmac *instance_p, u32 phy_address, /* Make sure no other PHY operation is currently in progress */ if ((!(FXMAC_READREG32(instance_p->config.base_address, FXMAC_NWSR_OFFSET) & - FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE) + FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE) { status = (FError)(FXMAC_ERR_PHY_BUSY); } @@ -742,4 +744,20 @@ FError FXmacPhyRead(FXmac *instance_p, u32 phy_address, status = (FError)(FT_SUCCESS); } return status; -} \ No newline at end of file +} + +boolean FXmacUsxLinkStatus(FXmac *instance_p) +{ + u32 reg = 0; + FASSERT(instance_p != NULL); + + reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_USX_STATUS_OFFSET); + if (reg & FXMAC_GEM_USX_STATUS_BLOCK_LOCK) + { + return TRUE; + } + else + { + return FALSE; + } +} diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.c index 4af6752555..f8ea684af2 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.c @@ -14,16 +14,18 @@ * FilePath: fxmac_phy.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for phy types. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac.h" #include "eth_ieee_reg.h" #include "fdebug.h" +#include "sdkconfig.h" #if defined(CONFIG_FXMAC_PHY_YT) #include "phy_yt.h" @@ -46,26 +48,26 @@ static FError FXmacDetect(FXmac *instance_p, u32 *phy_addr_p) FError ret; instance_b = instance_p; - for (phy_addr = 0; phy_addr < FT_XMAC_PHY_MAX_NUM; phy_addr++) + for (phy_addr = 0; phy_addr < FXMAC_PHY_MAX_NUM; phy_addr++) { ret = FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &phy_reg); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s, PHY operation is busy", __func__); + FXMAC_ERROR("Phy operation is busy."); return ret; } - FXMAC_INFO("PHY_STATUS_REG_OFFSET is %x \r\n", phy_reg); + FXMAC_INFO("Phy status reg is %x", phy_reg); if (phy_reg != 0xffff) { ret = FXmacPhyRead(instance_p, phy_addr, PHY_IDENTIFIER_1_REG, &phy_id1_reg); ret |= FXmacPhyRead(instance_p, phy_addr, PHY_IDENTIFIER_2_REG, &phy_id2_reg); - FXMAC_INFO("phy_id1_reg is 0x%x \r\n", phy_id1_reg); - FXMAC_INFO("phy_id2_reg is 0x%x \r\n", phy_id2_reg); + FXMAC_INFO("Phy id1 reg is 0x%x", phy_id1_reg); + FXMAC_INFO("Phy id2 reg is 0x%x", phy_id2_reg); if ((ret == FT_SUCCESS) && (phy_id2_reg != 0) && (phy_id1_reg != 0xffff) && (phy_id1_reg != 0xffff)) { *phy_addr_p = phy_addr; phy_addr_b = phy_addr; - FXMAC_INFO("phy_addr is 0x%x \r\n", phy_addr); + FXMAC_INFO("Phy addr is 0x%x", phy_addr); return FT_SUCCESS; } } @@ -84,12 +86,12 @@ static FError FXmacGetIeeePhySpeed(FXmac *instance_p, u32 phy_addr) FError ret; volatile s32 wait; - FXMAC_INFO("Start PHY autonegotiation "); + FXMAC_INFO("Start phy auto negotiation."); ret = FXmacPhyRead(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, &control); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); return ret; } control |= PHY_CONTROL_RESET_MASK; @@ -97,16 +99,16 @@ static FError FXmacGetIeeePhySpeed(FXmac *instance_p, u32 phy_addr) ret = FXmacPhyWrite(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, control); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,write PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,write PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); return ret; } for (wait = 0; wait < 100000; wait++) ; - FXMAC_INFO(" PHY reset end "); + FXMAC_INFO(" Phy reset end."); ret = FXmacPhyRead(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, &control); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); return ret; } @@ -115,16 +117,16 @@ static FError FXmacGetIeeePhySpeed(FXmac *instance_p, u32 phy_addr) ret = FXmacPhyWrite(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, control); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,write PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,write PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); return ret; } - FXMAC_INFO("Waiting for PHY to complete autonegotiation."); + FXMAC_INFO("Waiting for phy to complete auto negotiation."); ret = FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_CONTROL_REG_OFFSET is error", __func__, __LINE__); return ret; } @@ -136,60 +138,60 @@ static FError FXmacGetIeeePhySpeed(FXmac *instance_p, u32 phy_addr) ret = FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_STATUS_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_STATUS_REG_OFFSET is error", __func__, __LINE__); return ret; } if (negotitation_timeout_cnt++ >= 0xfff) { - FXMAC_ERROR("autonegotiation is error "); + FXMAC_ERROR("Auto negotiation is error."); return FXMAC_PHY_AUTO_AUTONEGOTIATION_FAILED; } } - FXMAC_INFO("autonegotiation complete "); + FXMAC_INFO("Auto negotiation complete."); ret = FXmacPhyRead(instance_p, phy_addr, PHY_SPECIFIC_STATUS_REG, &temp); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_SPECIFIC_STATUS_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_SPECIFIC_STATUS_REG is error", __func__, __LINE__); return ret; } - FXMAC_INFO("temp is %x \r\n", temp); + FXMAC_INFO("Temp is 0x%x", temp); ret = FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &temp2); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_STATUS_REG_OFFSET is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_STATUS_REG_OFFSET is error", __func__, __LINE__); return ret; } - FXMAC_INFO("temp2 is %x \r\n", temp2); + FXMAC_INFO("Temp2 is 0x%x", temp2); if (temp & (1 << 13)) { - FXMAC_INFO("duplex is full \r\n"); + FXMAC_INFO("Duplex is full."); instance_p->config.duplex = 1; } else { - FXMAC_INFO("duplex is half \r\n"); + FXMAC_INFO("Duplex is half."); instance_p->config.duplex = 0; } if ((temp & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_1000M) { - FXMAC_INFO("speed is 1000\r\n"); + FXMAC_INFO("Speed is 1000M."); instance_p->config.speed = 1000; } else if ((temp & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_100M) { - FXMAC_INFO("speed is 100\r\n"); + FXMAC_INFO("Speed is 100M."); instance_p->config.speed = 100; } else { - FXMAC_INFO("speed is 10\r\n"); + FXMAC_INFO("Speed is 10M."); instance_p->config.speed = 10; } @@ -200,8 +202,8 @@ void FxmaxLinkupCheck(void) { u16 temp; FXmacPhyRead(instance_b, phy_addr_b, PHY_SPECIFIC_STATUS_REG, &temp); - FXMAC_INFO("0x17 value is %x \r\n", temp); - FXMAC_INFO("linkup status is %x \r\n", temp & (1 << 10)); + FXMAC_INFO("Reg 0x17 value is 0x%x", temp); + FXMAC_INFO("Linkup status is 0x%x", temp & (1 << 10)); } @@ -213,12 +215,12 @@ static FError FXmacConfigureIeeePhySpeed(FXmac *instance_p, u32 phy_addr, u32 sp FError ret; u16 specific_reg = 0; - FXMAC_INFO("manual setting ,phy_addr is %d,speed %d, duplex_mode is %d \r\n", phy_addr, speed, duplex_mode); + FXMAC_INFO("Manual setting ,phy_addr is %d,speed %d, duplex_mode is %d.", phy_addr, speed, duplex_mode); ret = FXmacPhyRead(instance_p, phy_addr, PHY_AUTONEGO_ADVERTISE_REG, &autonereg); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_AUTONEGO_ADVERTISE_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_AUTONEGO_ADVERTISE_REG is error.", __func__, __LINE__); return ret; } @@ -227,7 +229,7 @@ static FError FXmacConfigureIeeePhySpeed(FXmac *instance_p, u32 phy_addr, u32 sp ret = FXmacPhyWrite(instance_p, phy_addr, PHY_AUTONEGO_ADVERTISE_REG, autonereg); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,write PHY_AUTONEGO_ADVERTISE_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,write PHY_AUTONEGO_ADVERTISE_REG is error.", __func__, __LINE__); return ret; } @@ -235,10 +237,10 @@ static FError FXmacConfigureIeeePhySpeed(FXmac *instance_p, u32 phy_addr, u32 sp ret = FXmacPhyRead(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, &control); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_AUTONEGO_ADVERTISE_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_AUTONEGO_ADVERTISE_REG is error.", __func__, __LINE__); return ret; } - FXMAC_INFO("PHY_CONTROL_REG_OFFSET is %x \r\n", control); + FXMAC_INFO("PHY_CONTROL_REG_OFFSET is 0x%x.", control); control &= ~PHY_CONTROL_LINKSPEED_1000M; @@ -274,48 +276,48 @@ static FError FXmacConfigureIeeePhySpeed(FXmac *instance_p, u32 phy_addr, u32 sp ret = FXmacPhyWrite(instance_p, phy_addr, PHY_CONTROL_REG_OFFSET, control); /* Technology Ability Field */ if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,write PHY_AUTONEGO_ADVERTISE_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,write PHY_AUTONEGO_ADVERTISE_REG is error.", __func__, __LINE__); return ret; } for (wait = 0; wait < 100000; wait++) ; - FXMAC_INFO("Manual selection completed \r\n"); + FXMAC_INFO("Manual selection completed."); ret = FXmacPhyRead(instance_p, phy_addr, PHY_SPECIFIC_STATUS_REG, &specific_reg); if (ret != FT_SUCCESS) { - FXMAC_ERROR("%s line is %d,read PHY_SPECIFIC_STATUS_REG is error", __func__, __LINE__); + FXMAC_ERROR("%s:%d,read PHY_SPECIFIC_STATUS_REG is error.", __func__, __LINE__); return ret; } - FXMAC_INFO("specific_reg is %x \r\n", specific_reg); + FXMAC_INFO("Specific reg is 0x%x.", specific_reg); if (specific_reg & (1 << 13)) { - FXMAC_INFO("duplex is full \r\n"); + FXMAC_INFO("Duplex is full."); instance_p->config.duplex = 1; } else { - FXMAC_INFO("duplex is half \r\n"); + FXMAC_INFO("Duplex is half."); instance_p->config.duplex = 0; } if ((specific_reg & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_1000M) { - FXMAC_INFO("speed is 1000\r\n"); + FXMAC_INFO("Speed is 1000M."); instance_p->config.speed = 1000; } else if ((specific_reg & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_100M) { - FXMAC_INFO("speed is 100\r\n"); + FXMAC_INFO("Speed is 100M."); instance_p->config.speed = 100; } else { - FXMAC_INFO("speed is 10\r\n"); + FXMAC_INFO("Speed is 10M."); instance_p->config.speed = 10; } @@ -341,10 +343,10 @@ FError FXmacPhyInit(FXmac *instance_p, u32 speed, u32 duplex_mode, u32 autonegot if (FXmacDetect(instance_p, &phy_addr) != FT_SUCCESS) { - FXMAC_ERROR("phy is not found"); + FXMAC_ERROR("Phy is not found."); return FXMAC_PHY_IS_NOT_FOUND; } - FXMAC_INFO("settings phy_addr is %d\n", phy_addr); + FXMAC_INFO("Setting phy addr is %d.", phy_addr); instance_p->phy_address = phy_addr; if (autonegotiation_en) { @@ -356,11 +358,11 @@ FError FXmacPhyInit(FXmac *instance_p, u32 speed, u32 duplex_mode, u32 autonegot } else { - FXMAC_INFO("Set the communication speed manually"); + FXMAC_INFO("Set the communication speed manually."); ret = FXmacConfigureIeeePhySpeed(instance_p, phy_addr, speed, duplex_mode); if (ret != FT_SUCCESS) { - FXMAC_ERROR("Failed to manually set the PHY"); + FXMAC_ERROR("Failed to manually set the phy."); return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.h index 49c1e1de38..b8f4b293b4 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_phy.h @@ -14,21 +14,23 @@ * FilePath: fxmac_phy.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for phy configuration. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef DRIVERS_ETH_FXMAC_PHY_H -#define DRIVERS_ETH_FXMAC_PHY_H +#ifndef FXMAC_PHY_H +#define FXMAC_PHY_H #ifdef __cplusplus extern "C" { #endif + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_sinit.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_sinit.c index 13a8592036..a9ac785158 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/fxmac_sinit.c @@ -14,24 +14,25 @@ * FilePath: fxmac_sinit.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for the implementation of the xmac driver's static + * initialization functionality. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "fxmac.h" #include "fparameters.h" -extern const FXmacConfig fxmac_cfg_tbl[FT_XMAC_NUM]; +extern const FXmacConfig fxmac_cfg_tbl[FXMAC_NUM]; const FXmacConfig *FXmacLookupConfig(u32 instance_id) { const FXmacConfig *cfg_ptr = NULL; u32 index; - - for (index = 0; index < (u32)FT_XMAC_NUM; index++) + for (index = 0; index < (u32)FXMAC_NUM; index++) { if (fxmac_cfg_tbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/eth_ieee_reg.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/eth_ieee_reg.h index 02ddcee2c0..3851bdeefa 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/eth_ieee_reg.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/eth_ieee_reg.h @@ -14,23 +14,24 @@ * FilePath: eth_ieee_reg.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for phys chip register definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ -#ifndef DRIVERS_ETH_PHY_IEEE_REG_H -#define DRIVERS_ETH_PHY_IEEE_REG_H +#ifndef ETH_IEEE_REG_H +#define ETH_IEEE_REG_H + +/***************************** Include Files *********************************/ +#include "ferror_code.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "ferror_code.h" /***************** Macros (Inline Functions) Definitions *********************/ diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.c b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.c index 9aeae51ed3..83f7726dfb 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.c +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.c @@ -14,11 +14,12 @@ * FilePath: phy_yt.c * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for yt PHYs chip * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #include "phy_yt.h" @@ -42,18 +43,18 @@ FError PhyYtCheckConnectStatus(void *instance_p, u32 phy_addr, EthPhyWrite write status = write_p(instance_p, phy_addr, 0x1e, 0xa001); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa001 to 0x1e failed."); return FETH_PHY_ERR_READ; } status = read_p(instance_p, phy_addr, 0x1f, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("read_p 0x1f failed"); + PHY_YT_ERROR("Read 0x1f reg failed."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("phy_reg0 status is 0x%x", phy_reg0); + PHY_YT_INFO("Phy reg0 status is 0x%x", phy_reg0); return FT_SUCCESS; } @@ -66,10 +67,10 @@ FError PhyYtSetLoopBack(void *instance_p, u32 phy_addr, EthPhyWrite write_p, Eth status = read_p(instance_p, phy_addr, 0, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("Error setup phy loopback"); + PHY_YT_ERROR("Error setup phy loopback."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("0 phy_reg0 is 0x%x \r\n", phy_reg0); + PHY_YT_INFO("Phy reg 0 is 0x%x", phy_reg0); /* * Enable loopback */ @@ -79,17 +80,17 @@ FError PhyYtSetLoopBack(void *instance_p, u32 phy_addr, EthPhyWrite write_p, Eth status = read_p(instance_p, phy_addr, 0, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("Error setup phy loopback"); + PHY_YT_ERROR("Error setup phy loopback."); return FETH_PHY_ERR_READ; } status = read_p(instance_p, phy_addr, 0, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("Error setup phy loopback"); + PHY_YT_ERROR("Error setup phy loopback."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("after 0 phy_reg0 is 0x%x \r\n", phy_reg0); + PHY_YT_INFO("Phy reg 0 is 0x%x", phy_reg0); return FT_SUCCESS; } @@ -104,7 +105,7 @@ FError PhyChangeModeToSgmii(void *instance_p, u32 phy_addr, EthPhyWrite write_p, status = write_p(instance_p, phy_addr, 0x1e, 0xa001); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa001 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } @@ -112,33 +113,32 @@ FError PhyChangeModeToSgmii(void *instance_p, u32 phy_addr, EthPhyWrite write_p, status = read_p(instance_p, phy_addr, 0x1f, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("read_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Read reg 0x1f failed."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("default 0xa001 status is 0x%x \r\n", phy_reg0); + PHY_YT_INFO("Default 0x1f status is 0x%x", phy_reg0); /* change mode to sds */ status = write_p(instance_p, phy_addr, 0x1e, 0xa001); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa001 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } status = write_p(instance_p, phy_addr, 0x1f, 0x8063); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0x8063 to reg 0x1f failed."); return FETH_PHY_ERR_READ; } - /* read changged mode */ status = write_p(instance_p, phy_addr, 0x1e, 0xa001); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa000 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa001 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } @@ -146,13 +146,11 @@ FError PhyChangeModeToSgmii(void *instance_p, u32 phy_addr, EthPhyWrite write_p, status = read_p(instance_p, phy_addr, 0x1f, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("read_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Read reg 0x1f failed."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("changged 0xa001 status is 0x%x \r\n", phy_reg0); - - + PHY_YT_INFO("Read reg 0x1f status is 0x%x", phy_reg0); return FT_SUCCESS; } @@ -162,60 +160,54 @@ FError PhyChangeModeToSds(void *instance_p, u32 phy_addr, EthPhyWrite write_p, E FError status; u16 phy_reg0 = 0; - /* read default mode */ status = write_p(instance_p, phy_addr, 0x1e, 0xa000); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa000 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa000 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } - status = read_p(instance_p, phy_addr, 0x1f, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("read_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Read reg 0x1f failed."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("default status is 0x%x \r\n", phy_reg0); + PHY_YT_INFO("Read reg 0x1f status is 0x%x \r\n", phy_reg0); /* change mode to sds */ status = write_p(instance_p, phy_addr, 0x1e, 0xa000); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa000 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } status = write_p(instance_p, phy_addr, 0x1f, 0x2); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Write 0x02 to reg 0x1f failed."); return FETH_PHY_ERR_READ; } - /* read changged mode */ status = write_p(instance_p, phy_addr, 0x1e, 0xa000); if (status != FT_SUCCESS) { - PHY_YT_ERROR("write_p 0xa000 to 0x1e failed"); + PHY_YT_ERROR("Write 0xa000 to reg 0x1e failed."); return FETH_PHY_ERR_READ; } - status = read_p(instance_p, phy_addr, 0x1f, &phy_reg0); if (status != FT_SUCCESS) { - PHY_YT_ERROR("read_p 0xa001 to 0x1e failed"); + PHY_YT_ERROR("Read reg 0x1f failed."); return FETH_PHY_ERR_READ; } - PHY_YT_INFO("changged status is 0x%x \r\n", phy_reg0); - - + PHY_YT_INFO("Read reg 0x1f status is 0x%x \r\n", phy_reg0); return FT_SUCCESS; } diff --git a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.h b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.h index 4640db8511..e223120d1b 100644 --- a/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.h +++ b/bsp/phytium/libraries/standalone/drivers/eth/fxmac/phy/yt/phy_yt.h @@ -14,30 +14,32 @@ * FilePath: phy_yt.h * Date: 2022-04-06 14:46:52 * LastEditTime: 2022-04-06 14:46:58 - * Description:  This file is for + * Description:  This file is for yt PHYs chip. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/06/16 first release */ #ifndef PHY_YT_H #define PHY_YT_H +#include "ferror_code.h" +#include "eth_ieee_reg.h" + #ifdef __cplusplus extern "C" { #endif -#include "ferror_code.h" -#include "eth_ieee_reg.h" - #define FETH_PHY_ERR_READ FT_MAKE_ERRCODE(ErrModBsp, ErrEthPhy, 0x1u) FError PhyYtSetLoopBack(void *instance_p, u32 phy_addr, EthPhyWrite write_p, EthPhyRead read_p); FError PhyYtCheckConnectStatus(void *instance_p, u32 phy_addr, EthPhyWrite write_p, EthPhyRead read_p); FError PhyChangeModeToSds(void *instance_p, u32 phy_addr, EthPhyWrite write_p, EthPhyRead read_p); FError PhyChangeModeToSgmii(void *instance_p, u32 phy_addr, EthPhyWrite write_p, EthPhyRead read_p); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/gic/Kconfig b/bsp/phytium/libraries/standalone/drivers/gic/Kconfig index 1bf1dc91df..9946994e6d 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/gic/Kconfig @@ -3,4 +3,4 @@ prompt "Use Generic Interrupt Controller v3" default y - + \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.c b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.c index b1fa4fb582..a1c96c46ce 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.c +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.c @@ -14,11 +14,12 @@ * FilePath: fgic.c * Date: 2022-03-28 09:30:23 * LastEditTime: 2022-03-28 09:30:24 - * Description:  This file is for + * Description: This file is for the minimum required function implementations for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ #include "fgic.h" @@ -77,7 +78,7 @@ static FError FGicWaitRwp(uintptr ctrl_base, WAIT_RWP_MODE wait_mode) } else { - FGIC_DEBUG_E(" wait_mode not in WAIT_RWP_MODE "); + FGIC_DEBUG_E(" wait_mode not in WAIT_RWP_MODE."); return FGIC_CTLR_ERR_TYPE; } @@ -85,7 +86,7 @@ static FError FGicWaitRwp(uintptr ctrl_base, WAIT_RWP_MODE wait_mode) { if (timeout_cnt ++ >= 0xffffff) { - FGIC_DEBUG_E(" wait rwp timeout "); + FGIC_DEBUG_E(" Wait rwp timeout."); return FGIC_CTLR_ERR_IN_GET; } } @@ -285,7 +286,7 @@ FError FGicIntEnable(FGic *instance_p, s32 int_id) if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicIntEnable"); + FGIC_DEBUG_E("int_id is over max spi num for FGicIntEnable."); return FGIC_CTLR_ERR_NUM; } @@ -318,7 +319,7 @@ FError FGicIntDisable(FGic *instance_p, s32 int_id) if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicIntDisable"); + FGIC_DEBUG_E("int_id is over max spi num for FGicIntDisable."); return FGIC_CTLR_ERR_NUM; } @@ -353,7 +354,7 @@ FError FGicSetPriority(FGic *instance_p, s32 int_id, u32 priority) if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicSetPriority"); + FGIC_DEBUG_E("int_id is over max spi num for FGicSetPriority."); return FGIC_CTLR_ERR_IN_GET; } @@ -387,7 +388,7 @@ u32 FGicGetPriority(FGic *instance_p, s32 int_id) if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicGetPriority"); + FGIC_DEBUG_E("int_id is over max spi num for FGicGetPriority."); return (u32)FGIC_CTLR_ERR_IN_GET; } @@ -420,7 +421,7 @@ FError FGicSetTriggerLevel(FGic *instance_p, s32 int_id, TRIGGER_LEVEL trigger_w if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicSetTriggerLevel"); + FGIC_DEBUG_E("int_id is over max spi num for FGicSetTriggerLevel."); return FGIC_CTLR_ERR_IN_SET; } @@ -459,7 +460,7 @@ u32 FGicGetTriggerLevel(FGic *instance_p, s32 int_id) if (int_id > instance_p->max_spi_num) { - FGIC_DEBUG_E("int_id is over max spi num for FGicGetTriggerLevel"); + FGIC_DEBUG_E("int_id is over max spi num for FGicGetTriggerLevel."); return (u32)FGIC_CTLR_ERR_IN_GET; } @@ -501,7 +502,7 @@ FError FGicSetSpiAffinityRouting(FGic *instance_p, s32 int_id, SPI_ROUTING_MODE if ((int_id > instance_p->max_spi_num) || (int_id <= FGIC_PPI_END_ID)) { - FGIC_DEBUG_E("int_id %d is out of range ", int_id); + FGIC_DEBUG_E("int_id %d is out of range.", int_id); return FGIC_CTLR_ERR_IN_SET; } @@ -532,7 +533,7 @@ FError FGicGetAffinityRouting(FGic *instance_p, s32 int_id, SPI_ROUTING_MODE *ro if ((int_id > instance_p->max_spi_num) || (int_id <= FGIC_PPI_END_ID)) { - FGIC_DEBUG_E("int_id %d is out of range ", int_id); + FGIC_DEBUG_E("int_id %d is out of range.", int_id); return (u32)FGIC_CTLR_ERR_IN_GET; } @@ -562,7 +563,7 @@ FError FGicGenerateSgi(FGic *instance_p, s32 int_id, u32 target_list, SGI_ROUTIN if (int_id > FGIC_SGI_END_ID) { - FGIC_DEBUG_E("int_id %d is out of range ", int_id); + FGIC_DEBUG_E("int_id %d is out of range.", int_id); return FGIC_CTLR_ERR_IN_SET; } diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.h b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.h index e08236e916..383de430d5 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.h +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.h @@ -14,20 +14,25 @@ * FilePath: fgic.h * Date: 2022-03-28 09:30:29 * LastEditTime: 2022-03-28 09:30:29 - * Description:  This file is for + * Description: This file is for detailed description of the device and driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ -#ifndef DRIVERS_GIC_FGIC_H -#define DRIVERS_GIC_FGIC_H +#ifndef FGIC_H +#define FGIC_H #include "ftypes.h" #include "ferror_code.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif #define FGIC_RSGI_AFF1_OFFSET 16 #define FGIC_RSGI_AFF2_OFFSET 32 @@ -106,4 +111,8 @@ void FGicSetPriorityGroup(FGic *instance_p, u32 binary_point); u32 FGicGetPriorityFilter(FGic *instance_p); u32 FGicGetPriorityGroup(FGic *instance_p); +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.S b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.S index 2cc1d927a3..ecd1af8c47 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.S +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.S @@ -14,15 +14,15 @@ * @FilePath: fgic_cpu_interface.S * @Date: 2022-03-29 18:04:23 * @LastEditTime: 2022-03-29 18:04:27 - * @Description:  This file is for + * @Description:  This file is Mapping of MSR and MRS to physical and virtual CPU interface registers. * - * @Modify History: + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ - #ifdef __aarch64__ /* diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.h b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.h index 9bcdd84c7d..5535000552 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.h +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_cpu_interface.h @@ -14,17 +14,24 @@ * FilePath: fgic_cpu_interface.h * Date: 2022-03-28 14:55:27 * LastEditTime: 2022-03-28 14:55:27 - * Description:  This file is for + * Description:  This file is for gic register definition and operation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ -#ifndef DRIVERS_CPU_INTERFACE_H -#define DRIVERS_CPU_INTERFACE_H + +#ifndef FGIC_CPU_INTERFACE_H +#define FGIC_CPU_INTERFACE_H + #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif #define FGIC_ICC_SGI1R_INTID_MASK 0xFULL /* The INTID of the SGI. */ @@ -99,18 +106,18 @@ void FGicSetICC_ASGI1R(u32 intnum, u32 target_list, GICC_SGIR_IRM_BITS mode, u64 /* For AArch32 state, accesses to GIC registers that are visible in the System register */ #define FGIC_SYS_READ32(CR, Rt) __asm__ volatile("MRC " CR \ - : "=r"(Rt) \ - : \ - : "memory") + : "=r"(Rt) \ + : \ + : "memory") #define FGIC_SYS_WRITE32(CR, Rt) __asm__ volatile("MCR " CR \ - : \ - : "r"(Rt) \ - : "memory") + : \ + : "r"(Rt) \ + : "memory") #define FGIC_SYS_WRITE64(cp, op1, Rt, CRm) __asm__ volatile("MCRR p" #cp ", " #op1 ", %Q0, %R0, c" #CRm \ - : \ - : "r"(Rt) \ - : "memory") + : \ + : "r"(Rt) \ + : "memory") #define ICC_IAR0 "p15, 0, %0, c12, c8, 0" @@ -543,5 +550,9 @@ static inline void FGicSetICC_ASGI1R(u32 intnum_bit, u32 target_list, GICC_SGIR_ #endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_distributor.h b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_distributor.h index 1c163dd1fb..b2fe66fed6 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_distributor.h +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_distributor.h @@ -14,19 +14,26 @@ * FilePath: fgic_distributor.h * Date: 2022-03-28 15:18:56 * LastEditTime: 2022-03-28 15:18:56 - * Description:  This file is for + * Description: This file is for gic distributor implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ -#ifndef DRIVERS_GIC_FGIC_DISTRIBUTOR_H -#define DRIVERS_GIC_FGIC_DISTRIBUTOR_H + +#ifndef FGIC_DISTRIBUTOR_H +#define FGIC_DISTRIBUTOR_H #include "fgic.h" #include "fgic_hw.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define GICD_ICFGR_MODE TRIGGER_LEVEL #define GICD_IRPITER_MODE SPI_ROUTING_MODE @@ -162,4 +169,8 @@ static inline u32 FGicGetSpiSecurity(uintptr dist_base, u32 spi_id) return ((group_modifier << 1) | group_status); } +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_g.c b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_g.c index 3f40151fc7..060e87806d 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_g.c +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_g.c @@ -14,12 +14,14 @@ * FilePath: fgic_g.c * Date: 2022-03-30 14:57:43 * LastEditTime: 2022-03-30 14:57:43 - * Description:  This file is for + * Description:  This file is for gic static configuration implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ + #include "fparameters.h" #include "fgic.h" @@ -27,6 +29,6 @@ FGicConfig fgic_config[FGIC_NUM] = { { .instance_id = 0, /* Id of device */ - .dis_base = GICV3_DISTRIBUTOR_BASEADDRESS, /* Distributor base address */ + .dis_base = GICV3_DISTRIBUTOR_BASE_ADDR, /* Distributor base address */ } }; \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_hw.h b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_hw.h index a8947ebbef..aafc131c27 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_hw.h @@ -14,20 +14,26 @@ * FilePath: fgic_hw.h * Date: 2022-03-24 11:44:48 * LastEditTime: 2022-03-24 11:44:48 - * Description:  This file is for + * Description: This file is for gic register definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ -#ifndef DRIVERS_GIC_FGIC_HW_H -#define DRIVERS_GIC_FGIC_HW_H +#ifndef FGIC_HW_H +#define FGIC_HW_H #include "ftypes.h" #include "fio.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* Distributor */ #define FGIC_GICD_CTLR_OFFSET 0x00000000U /* Distributor Control Register ,RW */ #define FGIC_GICD_TYPER_OFFSET 0x00000004U /* Interrupt Controller Type Register ,RO */ @@ -312,4 +318,8 @@ #define FGIC_GICR_NSACR_WRITE(sgi_base, reg) FGIC_WRITEREG32(sgi_base , FGIC_GICR_NSACR_OFFSET, reg) #define FGIC_GICR_NSACR_READ(sgi_base) FGIC_READREG32(sgi_base , FGIC_GICR_NSACR_OFFSET) +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_redistributor.h b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_redistributor.h index 23f3bf147f..b966c7d5f7 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_redistributor.h +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_redistributor.h @@ -14,19 +14,25 @@ * FilePath: fgic_redistributor.h * Date: 2022-03-28 14:57:01 * LastEditTime: 2022-03-28 14:57:01 - * Description:  This file is for + * Description:  This file is for gic redistributor implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ -#ifndef DRIVERS_GIC_FGIC_REDISTRIBUTOR_H -#define DRIVERS_GIC_FGIC_REDISTRIBUTOR_H + +#ifndef FGIC_REDISTRIBUTOR_H +#define FGIC_REDISTRIBUTOR_H #include "fgic.h" #include "fgic_hw.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif typedef enum { @@ -169,5 +175,9 @@ static inline u32 FGicNonSecureAccessRead(uintptr redis_base) return FGIC_GICR_NSACR_READ(redis_base + FGIC_GICR_SGI_BASE_OFFSET); } +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_sinit.c b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_sinit.c index 28b9ce2b29..2575462de0 100644 --- a/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic_sinit.c @@ -14,12 +14,15 @@ * FilePath: fgic_sinit.c * Date: 2022-03-30 15:00:29 * LastEditTime: 2022-03-30 15:00:29 - * Description:  This file is for + * Description: This file is for gic static variables implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/4/16 init commit */ + + #include "fgic.h" extern FGicConfig fgic_config[FGIC_NUM]; diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/Kconfig b/bsp/phytium/libraries/standalone/drivers/i2c/Kconfig index 6f34251dd2..1195673525 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/i2c/Kconfig @@ -4,5 +4,5 @@ config USE_FI2C default n help Include FI2C driver component - - + + \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.c index 43899808a8..f76e77bcf1 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.c @@ -12,13 +12,15 @@ * * * FilePath: fi2c.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:58 - * Description:  This files is for + * Description:  This file is for complete user external interface * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/2/18 modified to support i2c */ @@ -50,20 +52,12 @@ static const char *FI2C_ERROR_CODE_MSG[FI2C_NUM_OF_ERR_CODE] = { "FI2C_SUCCESS : fi2c success", "FI2C_ERR_INVAL_PARM : fi2c invalid input parameters", - "FI2C_ERR_NOT_READY : fi2c driver not ready", + "FI2C_ERR_NOT_READY : fi2c driver is not ready", "FI2C_ERR_TIMEOUT : fi2c wait timeout", - "FI2C_ERR_NOT_SUPPORT : fi2c non support operation", + "FI2C_ERR_NOT_SUPPORT : fi2c not support operation", "FI2C_ERR_INVAL_STATE : fi2c invalid state" }; -/*****************************************************************************/ - -/* 此文件主要为了完成用户对外接口,用户可以使用这些接口直接开始工作 */ - -/* - 包括用户API的定义和实现 - - 同时包含必要的OPTION方法,方便用户进行配置 - - 如果驱动可以直接进行I/O操作,在此源文件下可以将API 进行实现 */ - /** * @name: FI2cCfgInitialize * @msg: 完成I2C驱动实例的初始化,使之可以使用 @@ -86,7 +80,7 @@ FError FI2cCfgInitialize(FI2c *instance_p, const FI2cConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FI2C_ERROR("device is already initialized!!!"); + FI2C_ERROR("Device is already initialized!!!"); return FI2C_ERR_INVAL_STATE; } @@ -164,11 +158,15 @@ static FError FI2cReset(FI2c *instance_p) ret = FI2cSetSpeed(base_addr, config_p->speed_rate); if (FI2C_SUCCESS == ret) - ret = FI2cSetEnable(base_addr, TRUE); /* enable i2c ctrl */ + { + ret = FI2cSetEnable(base_addr, TRUE); /* enable i2c ctrl */ + } /* if init successed, and i2c is in slave mode, set slave address */ if ((FI2C_SUCCESS == ret) && (FI2C_SLAVE == config_p->work_mode)) + { ret = FI2cSetSar(base_addr, config_p->slave_addr); + } return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.h b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.h index 505b310f85..9ab4c590da 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.h +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c.h @@ -12,24 +12,21 @@ * * * FilePath: fi2c.h - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:37:04 - * Description:  This files is for + * Description:  This file is for complete user external interface definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/2/18 modified to support i2c */ -#ifndef DRIVERS_I2C_FI2C_H -#define DRIVERS_I2C_FI2C_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FI2C_H +#define FI2C_H /***************************** Include Files *********************************/ @@ -37,6 +34,12 @@ extern "C" #include "fassert.h" #include "ferror_code.h" #include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ #define FI2C_SUCCESS FT_SUCCESS #define FI2C_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspI2c, 1) diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_g.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_g.c index 92e122f0ad..3c1db4baac 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_g.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_g.c @@ -14,11 +14,13 @@ * FilePath: fi2c_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:36:14 - * Description:  This files is for + * Description:  This file is for I2C static configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/02/18 add e2000 configs */ @@ -44,100 +46,59 @@ * @name: FI2C_CONFIG_TBL * @msg: I2C驱动的默认配置参数 */ -#if defined(CONFIG_TARGET_E2000) -const FI2cConfig FI2C_CONFIG_TBL[I2C_INSTANCE_NUM] = +const FI2cConfig FI2C_CONFIG_TBL[FI2C_NUM] = { - [I2C_INSTANCE_0] = + [FI2C0_ID] = { - .instance_id = I2C_INSTANCE_0, - .base_addr = I2C_0_BASEADDR, - .irq_num = I2C_0_INTR_IRQ, + .instance_id = FI2C0_ID, + .base_addr = FI2C0_BASE_ADDR, + .irq_num = FI2C0_IRQ_NUM, .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, + .ref_clk_hz = FI2C_CLK_FREQ_HZ, .work_mode = FI2C_MASTER, .slave_addr = 0, .use_7bit_addr = TRUE, .speed_rate = FI2C_SPEED_STANDARD_RATE }, - [I2C_INSTANCE_1] = +#if defined(CONFIG_TARGET_E2000) || defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) + [FI2C1_ID] = { - .instance_id = I2C_INSTANCE_1, - .base_addr = I2C_1_BASEADDR, - .irq_num = I2C_1_INTR_IRQ, + .instance_id = FI2C1_ID, + .base_addr = FI2C1_BASE_ADDR, + .irq_num = FI2C1_IRQ_NUM, .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, + .ref_clk_hz = FI2C_CLK_FREQ_HZ, .work_mode = FI2C_MASTER, .slave_addr = 0, .use_7bit_addr = TRUE, .speed_rate = FI2C_SPEED_STANDARD_RATE }, - [I2C_INSTANCE_2] = + [FI2C2_ID] = { - .instance_id = I2C_INSTANCE_2, - .base_addr = I2C_2_BASEADDR, - .irq_num = I2C_2_INTR_IRQ, + .instance_id = FI2C2_ID, + .base_addr = FI2C2_BASE_ADDR, + .irq_num = FI2C2_IRQ_NUM, .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, + .ref_clk_hz = FI2C_CLK_FREQ_HZ, + .work_mode = FI2C_MASTER, + .slave_addr = 0, + .use_7bit_addr = TRUE, + .speed_rate = FI2C_SPEED_STANDARD_RATE + }, +#endif +#if defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) + [FI2C3_ID] = + { + .instance_id = FI2C3_ID, + .base_addr = FI2C3_BASE_ADDR, + .irq_num = FI2C3_IRQ_NUM, + .irq_prority = 0, + .ref_clk_hz = FI2C_CLK_FREQ_HZ, .work_mode = FI2C_MASTER, .slave_addr = 0, .use_7bit_addr = TRUE, .speed_rate = FI2C_SPEED_STANDARD_RATE } +#endif }; -#endif - -#if defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) -const FI2cConfig FI2C_CONFIG_TBL[I2C_INSTANCE_NUM] = -{ - [I2C_INSTANCE_0] = - { - .instance_id = I2C_INSTANCE_0, - .base_addr = I2C_0_BASEADDR, - .irq_num = I2C_0_INTR_IRQ, - .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, - .work_mode = FI2C_MASTER, - .slave_addr = 0, - .use_7bit_addr = TRUE, - .speed_rate = FI2C_SPEED_STANDARD_RATE - }, - [I2C_INSTANCE_1] = - { - .instance_id = I2C_INSTANCE_1, - .base_addr = I2C_1_BASEADDR, - .irq_num = I2C_1_INTR_IRQ, - .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, - .work_mode = FI2C_MASTER, - .slave_addr = 0, - .use_7bit_addr = TRUE, - .speed_rate = FI2C_SPEED_STANDARD_RATE - }, - - [I2C_INSTANCE_2] = - { - .instance_id = I2C_INSTANCE_2, - .base_addr = I2C_2_BASEADDR, - .irq_num = I2C_2_INTR_IRQ, - .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, - .work_mode = FI2C_MASTER, - .slave_addr = 0, - .use_7bit_addr = TRUE, - .speed_rate = FI2C_SPEED_STANDARD_RATE - }, - [I2C_INSTANCE_3] = - { - .instance_id = I2C_INSTANCE_3, - .base_addr = I2C_3_BASEADDR, - .irq_num = I2C_3_INTR_IRQ, - .irq_prority = 0, - .ref_clk_hz = I2C_REF_CLK_HZ, - .work_mode = FI2C_MASTER, - .slave_addr = 0, - .use_7bit_addr = TRUE, - .speed_rate = FI2C_SPEED_STANDARD_RATE - } -}; -#endif diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.c index 6ce4679b14..efe7926ae3 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.c @@ -12,13 +12,15 @@ * * * FilePath: fi2c_hw.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:22 - * Description:  This files is for + * Description:  This file is for I2C register read/write operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/02/18 support slave mode */ /***************************** Include Files *********************************/ @@ -102,7 +104,7 @@ FError FI2cSetEnable(uintptr addr, boolean enable) } while (0 != timeout--); - FI2C_ERROR("timeout in %sabling I2C ctrl", enable ? "en" : "dis"); + FI2C_ERROR("Timeout in %sabling I2C ctrl.", enable ? "en" : "dis"); return FI2C_ERR_TIMEOUT; } @@ -193,11 +195,17 @@ static FError FI2cCalcSpeedCfg(uintptr addr, u32 speed, u32 bus_clk_hz, FI2cSpee u32 spk_cnt = 0; if (FI2C_SPEED_FAST_RATE <= speed) + { speed_cfg_p->speed_mode = FI2C_FAST_SPEED; + } else if (FI2C_SPEED_STANDARD_RATE <= speed) + { speed_cfg_p->speed_mode = FI2C_STANDARD_SPEED; + } else + { return FI2C_ERR_INVAL_PARM; + } spk_cnt = FI2C_READ_REG32(addr, FI2C_FS_SPKLEN_OFFSET); return FI2cCalcTiming(bus_clk_hz, spk_cnt, speed_cfg_p); @@ -218,9 +226,11 @@ FError FI2cSetSpeed(uintptr addr, u32 speed_rate) u32 reg_val; memset(&speed_cfg, 0, sizeof(speed_cfg)); - ret = FI2cCalcSpeedCfg(addr, speed_rate, I2C_REF_CLK_HZ, &speed_cfg); + ret = FI2cCalcSpeedCfg(addr, speed_rate, FI2C_CLK_FREQ_HZ, &speed_cfg); if (FI2C_SUCCESS != ret) + { return ret; + } /* get enable setting for restore later */ enable_status = FI2cGetEnable(addr); @@ -229,26 +239,28 @@ FError FI2cSetSpeed(uintptr addr, u32 speed_rate) reg_val = ((FI2C_READ_REG32(addr, FI2C_CON_OFFSET)) & (~FI2C_CON_SPEED_MASK)); switch (speed_cfg.speed_mode) { - case FI2C_STANDARD_SPEED: - reg_val |= FI2C_CON_STD_SPEED; - FI2C_WRITE_REG32(addr, FI2C_SS_SCL_HCNT_OFFSET, speed_cfg.scl_hcnt); - FI2C_WRITE_REG32(addr, FI2C_SS_SCL_LCNT_OFFSET, speed_cfg.scl_lcnt); - break; - case FI2C_FAST_SPEED: - reg_val |= FI2C_CON_FAST_SPEED; - FI2C_WRITE_REG32(addr, FI2C_FS_SCL_HCNT_OFFSET, speed_cfg.scl_hcnt); - FI2C_WRITE_REG32(addr, FI2C_FS_SCL_LCNT_OFFSET, speed_cfg.scl_lcnt); - break; - default: - ret |= FI2C_ERR_INVAL_PARM; - break; + case FI2C_STANDARD_SPEED: + reg_val |= FI2C_CON_STD_SPEED; + FI2C_WRITE_REG32(addr, FI2C_SS_SCL_HCNT_OFFSET, speed_cfg.scl_hcnt); + FI2C_WRITE_REG32(addr, FI2C_SS_SCL_LCNT_OFFSET, speed_cfg.scl_lcnt); + break; + case FI2C_FAST_SPEED: + reg_val |= FI2C_CON_FAST_SPEED; + FI2C_WRITE_REG32(addr, FI2C_FS_SCL_HCNT_OFFSET, speed_cfg.scl_hcnt); + FI2C_WRITE_REG32(addr, FI2C_FS_SCL_LCNT_OFFSET, speed_cfg.scl_lcnt); + break; + default: + ret |= FI2C_ERR_INVAL_PARM; + break; } FI2C_WRITE_REG32(addr, FI2C_CON_OFFSET, reg_val); /* Configure SDA Hold Time if required */ if (0 != speed_cfg.sda_hold) + { FI2C_WRITE_REG32(addr, FI2C_SDA_HOLD_OFFSET, speed_cfg.sda_hold); + } /* Restore back i2c now speed set */ if (FI2C_IC_ENABLE == enable_status) @@ -279,7 +291,7 @@ FError FI2cWaitStatus(uintptr addr, u32 stat_bit) if (FI2C_TIMEOUT <= timeout) { - FI2C_ERROR("timeout when wait status: 0x%x", stat_bit); + FI2C_ERROR("Timeout when wait status: 0x%x.", stat_bit); return FI2C_ERR_TIMEOUT; } @@ -298,10 +310,10 @@ FError FI2cWaitBusBusy(uintptr addr) u32 ret = FI2C_SUCCESS; if (((FI2C_READ_REG32(addr, FI2C_STATUS_OFFSET)) & FI2C_STATUS_MST_ACTIVITY) && - (FI2C_SUCCESS != FI2cWaitStatus(addr, FI2C_STATUS_TFE))) + (FI2C_SUCCESS != FI2cWaitStatus(addr, FI2C_STATUS_TFE))) { ret = FI2C_ERR_TIMEOUT; - FI2C_ERROR("timeout when wait i2c bus busy"); + FI2C_ERROR("Timeout when wait i2c bus busy."); } return ret; @@ -321,13 +333,19 @@ FError FI2cSetTar(uintptr addr, u32 tar_addr) u32 reg_val = 0; if (FI2C_IC_ENABLE == enable_status) + { ret = FI2cSetEnable(addr, FALSE); + } if (FI2C_SUCCESS == ret) + { FI2C_WRITE_REG32(addr, FI2C_TAR_OFFSET, (tar_addr & FI2C_IC_TAR_MASK)); + } if (FI2C_IC_ENABLE == enable_status) + { ret = FI2cSetEnable(addr, TRUE); + } return ret; } @@ -346,13 +364,19 @@ FError FI2cSetSar(uintptr addr, u32 sar_addr) u32 reg_val = 0; if (FI2C_IC_ENABLE == enable_status) + { ret = FI2cSetEnable(addr, FALSE); + } if (FI2C_SUCCESS == ret) + { FI2C_WRITE_REG32(addr, FI2C_SAR_OFFSET, (sar_addr & FI2C_IC_SAR_MASK)); + } if (FI2C_IC_ENABLE == enable_status) + { ret = FI2cSetEnable(addr, TRUE); + } return ret; } @@ -377,7 +401,7 @@ FError FI2cFlushRxFifo(uintptr addr) if (FI2C_TIMEOUT < ++timeout) { ret = FI2C_TIMEOUT; - FI2C_ERROR("timeout when flush fifo"); + FI2C_ERROR("Timeout when flush fifo."); break; } } @@ -406,28 +430,44 @@ u32 FI2cClearIntrBits(uintptr addr, u32 *last_err_p) } if (stat & FI2C_INTR_RX_UNDER) + { FI2C_READ_REG32(addr, FI2C_CLR_RX_UNDER_OFFSET); + } if (stat & FI2C_INTR_RX_OVER) + { FI2C_READ_REG32(addr, FI2C_CLR_RX_OVER_OFFSET); + } if (stat & FI2C_INTR_TX_OVER) + { FI2C_READ_REG32(addr, FI2C_CLR_TX_OVER_OFFSET); + } if (stat & FI2C_INTR_RX_DONE) + { FI2C_READ_REG32(addr, FI2C_CLR_RX_DONE_OFFSET); + } if (stat & FI2C_INTR_ACTIVITY) + { FI2C_READ_REG32(addr, FI2C_CLR_ACTIVITY_OFFSET); + } if (stat & FI2C_INTR_STOP_DET) + { FI2C_READ_REG32(addr, FI2C_CLR_STOP_DET_OFFSET); + } if (stat & FI2C_INTR_START_DET) + { FI2C_READ_REG32(addr, FI2C_CLR_START_DET_OFFSET); + } if (stat & FI2C_INTR_GEN_CALL) + { FI2C_READ_REG32(addr, FI2C_CLR_GEN_CALL_OFFSET); + } return stat; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.h b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.h index 1a39e67968..d082045b23 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_hw.h @@ -12,18 +12,20 @@ * * * FilePath: fi2c_hw.h - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:32 - * Description:  This files is for + * Description:  This file is for I2C register definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/02/18 add fi2c_slave mode */ -#ifndef DRIVERS_I2C_FI2C_HW_H -#define DRIVERS_I2C_FI2C_HW_H +#ifndef FI2C_HW_H +#define FI2C_HW_H /* - 传入模块基地址,不能复杂结构体 - hardware interface of device || low-level driver function prototypes @@ -34,10 +36,6 @@ 3. 一些简单外设提供直接操作接口 4. 可以定义一些状态的接口,用于响应驱动状态的变化 */ -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "fparameters.h" @@ -45,6 +43,11 @@ extern "C" #include "ferror_code.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /** @name Register Map diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_intr.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_intr.c index 85ebbd2af1..32ad762321 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_intr.c @@ -12,13 +12,15 @@ * * * FilePath: fi2c_intr.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:38 - * Description:  This files is for + * Description:  This file is for I2C interrupt operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/02/18 add fi2c_master interrupt and support slave mode */ /***************************** Include Files *********************************/ @@ -117,7 +119,7 @@ static void FI2cMasterIntrTxEmptyHandler(FI2c *instance_p) FI2C_DATA_CMD_WRITE | FI2C_DATA_CMD_STOP; instance_p->txframe.data_buff++; - FI2C_INFO("Write Stop Singal"); + FI2C_INFO("Write Stop Singal."); } else if (instance_p->status == STATUS_READ_IN_PROGRESS) { @@ -265,7 +267,7 @@ u32 FI2cGetIntr(FI2c *instance_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } @@ -287,13 +289,13 @@ FError FI2cMasterSetupIntr(FI2c *instance_p, u32 mask) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_MASTER != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be master"); + FI2C_ERROR("i2c work mode shall be master."); return FI2C_ERR_INVAL_STATE; } @@ -417,13 +419,13 @@ FError FI2cSlaveSetupIntr(FI2c *instance_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_SLAVE != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be slave"); + FI2C_ERROR("i2c work mode shall be slave."); return FI2C_ERR_INVAL_STATE; } diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_master.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_master.c index 49afc9cbc3..da45d42a31 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_master.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_master.c @@ -12,23 +12,17 @@ * * * FilePath: fi2c_master.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:46 - * Description:  This files is for + * Description:  This file is for i2c master drivers * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit + * 1.1 liushengming 2022/2/18 add poll mode and intr mode */ - -/* - - 一些驱动模块,直接操作硬件的I/O接口,无法实现有意义的操作,此时需要针对中间件或者用户使用习惯设计此模块 (i2c,nand,eth) - - 部分场景适用, 分角色的 I/O 操作 - - 此模块的函数原型,在fooxx.h 中声明一次,方便用户或者中间件层调用 - -*/ - /***************************** Include Files *********************************/ #include "fio.h" @@ -36,7 +30,6 @@ #include "fdebug.h" #include "fi2c_hw.h" #include "fi2c.h" -#include "finterrupt.h" /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -72,15 +65,21 @@ static FError FI2cMasterStartTrans(FI2c *instance_p, u32 mem_addr, u8 mem_byte_l ret = FI2cWaitBusBusy(base_addr); if (FI2C_SUCCESS != ret) + { return ret; + } ret = FI2cSetTar(base_addr, instance_p->config.slave_addr); /* 设备地址 */ if (FI2C_SUCCESS != ret) + { return ret; + } while (addr_len) { ret = FI2cWaitStatus(base_addr, FI2C_STATUS_TFNF); if (FI2C_SUCCESS != ret) + { break; + } if (FI2C_GET_STATUS(base_addr) & FI2C_STATUS_TFNF) { addr_len--; @@ -131,7 +130,9 @@ static FError FI2cMasterStopTrans(FI2c *instance_p) ret = FI2cWaitBusBusy(base_addr); if (FI2C_SUCCESS == ret) + { ret = FI2cFlushRxFifo(base_addr); + } return ret; } @@ -160,19 +161,21 @@ FError FI2cMasterReadPoll(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, u8 *b if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_MASTER != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be master"); + FI2C_ERROR("i2c work mode shall be master."); return FI2C_ERR_INVAL_STATE; } ret = FI2cMasterStartTrans(instance_p, mem_addr, mem_byte_len, FI2C_DATA_CMD_WRITE); if (FI2C_SUCCESS != ret) + { return ret; + } /*for trigger rx intr*/ while (tx_len > 0 || rx_len > 0) { @@ -214,7 +217,7 @@ FError FI2cMasterReadPoll(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, u8 *b else if (FI2C_TIMEOUT < (++trans_timeout)) { ret = FI2C_ERR_TIMEOUT; - FI2C_ERROR("timeout in i2c master read"); + FI2C_ERROR("timeout in i2c master read."); break; } } @@ -248,18 +251,20 @@ FError FI2cMasterWritePoll(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_MASTER != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be master"); + FI2C_ERROR("i2c work mode shall be master."); return FI2C_ERR_INVAL_STATE; } ret = FI2cMasterStartTrans(instance_p, mem_addr, mem_byte_len, FI2C_DATA_CMD_WRITE); if (FI2C_SUCCESS != ret) + { return ret; + } while (buf_idx) { tx_limit = FI2C_IIC_FIFO_MAX_LV - FI2C_READ_REG32(base_addr, FI2C_TXFLR_OFFSET); @@ -272,7 +277,7 @@ FError FI2cMasterWritePoll(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons reg_val = (FI2C_DATA_MASK & *buf_p) | FI2C_DATA_CMD_WRITE | FI2C_DATA_CMD_STOP; - FI2C_INFO("Write Stop Singal"); + FI2C_INFO("Write Stop Singal."); } else { @@ -288,7 +293,7 @@ FError FI2cMasterWritePoll(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons else if (FI2C_TIMEOUT < ++trans_timeout) { ret = FI2C_ERR_TIMEOUT; - FI2C_ERROR("timeout in i2c master write"); + FI2C_ERROR("Timeout in i2c master write."); break; } } @@ -320,12 +325,12 @@ FError FI2cMasterReadIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, u8 *b if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_MASTER != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be master"); + FI2C_ERROR("i2c work mode shall be master."); return FI2C_ERR_INVAL_STATE; } @@ -336,7 +341,7 @@ FError FI2cMasterReadIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, u8 *b if (FI2C_TIMEOUT < (++trans_timeout)) { ret = FI2C_ERR_TIMEOUT; - FI2C_ERROR("timeout in i2c master read intr."); + FI2C_ERROR("Timeout in i2c master read intr."); break; } } @@ -348,12 +353,16 @@ FError FI2cMasterReadIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, u8 *b ret = FI2cMasterStartTrans(instance_p, mem_addr, mem_byte_len, FI2C_DATA_CMD_WRITE); instance_p->status = STATUS_READ_IN_PROGRESS; if (FI2C_SUCCESS != ret) + { return ret; + } mask = FI2C_GET_INTRRUPT_MASK(instance_p->config.base_addr); mask |= FI2C_INTR_MASTER_RD_MASK; ret = FI2cMasterSetupIntr(instance_p, mask); if (FI2C_SUCCESS != ret) + { return ret; + } return ret; } @@ -375,13 +384,13 @@ FError FI2cMasterWriteIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons u32 trans_timeout = 0; if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FI2C_ERROR("i2c driver not ready"); + FI2C_ERROR("i2c driver is not ready."); return FI2C_ERR_NOT_READY; } if (FI2C_MASTER != instance_p->config.work_mode) { - FI2C_ERROR("i2c work mode shall be master"); + FI2C_ERROR("i2c work mode shall be master."); return FI2C_ERR_INVAL_STATE; } while (instance_p->status != STATUS_IDLE) @@ -391,7 +400,7 @@ FError FI2cMasterWriteIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons if (FI2C_TIMEOUT < (++trans_timeout)) { ret = FI2C_ERR_TIMEOUT; - FI2C_ERROR("timeout in i2c master write intr."); + FI2C_ERROR("Timeout in i2c master write intr."); break; } } @@ -400,12 +409,16 @@ FError FI2cMasterWriteIntr(FI2c *instance_p, u32 mem_addr, u8 mem_byte_len, cons instance_p->txframe.tx_cnt = 0; ret = FI2cMasterStartTrans(instance_p, mem_addr, mem_byte_len, FI2C_DATA_CMD_WRITE); if (FI2C_SUCCESS != ret) + { return ret; + } instance_p->status = STATUS_WRITE_IN_PROGRESS; mask = FI2C_GET_INTRRUPT_MASK(instance_p->config.base_addr); mask |= FI2C_INTR_MASTER_WR_MASK; ret = FI2cMasterSetupIntr(instance_p, mask); if (FI2C_SUCCESS != ret) + { return ret; + } return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_sinit.c b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_sinit.c index 8ea6a12dec..03c4e69b8d 100644 --- a/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/i2c/fi2c/fi2c_sinit.c @@ -12,20 +12,16 @@ * * * FilePath: fi2c_sinit.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-01 14:53:42 * LastEditTime: 2022-02-18 08:36:52 - * Description:  This files is for + * Description:  This file is for implementation of driver's static initialization functionality * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/11/1 first commit */ - - -/* - This file contains the implementation of driver's static initialization functionality. -- 驱动静态初始化 */ - /***************************** Include Files *********************************/ #include "ftypes.h" @@ -40,7 +36,7 @@ /************************** Variable Definitions *****************************/ -extern const FI2cConfig FI2C_CONFIG_TBL[I2C_INSTANCE_NUM]; +extern const FI2cConfig FI2C_CONFIG_TBL[FI2C_NUM]; /************************** Function Prototypes ******************************/ /** * @name: FI2cLookupConfig @@ -53,7 +49,7 @@ const FI2cConfig *FI2cLookupConfig(u32 instance_id) const FI2cConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)I2C_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FI2C_NUM; index++) { if (FI2C_CONFIG_TBL[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/Kconfig b/bsp/phytium/libraries/standalone/drivers/ipc/Kconfig index 92b76a91f6..2012b165d2 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/ipc/Kconfig @@ -5,5 +5,5 @@ config ENABLE_FSEMAPHORE depends on TARGET_E2000S || TARGET_E2000D || TARGET_E2000Q help Select FSemaphore driver component - - + + \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.c b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.c index 6409551a3a..e74a1fa2ba 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.c +++ b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.c @@ -14,7 +14,7 @@ * FilePath: fsemaphore.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for semaphore user api implmentation + * Description:  This file is for semaphore user api implmentation * * Modify History: * Ver   Who        Date         Changes @@ -62,21 +62,25 @@ FError FSemaCfgInitialize(FSema *const instance, const FSemaConfig *input_config { FASSERT(instance && input_config); uintptr base_addr = input_config->base_addr; - FASSERT_MSG((0 != base_addr), "invalid base addr"); + FASSERT_MSG((0 != base_addr), "invalid base addr."); FError ret = FSEMA_SUCCESS; if (FT_COMPONENT_IS_READY == instance->is_ready) { - FSEMA_WARN("device is already initialized!!!"); + FSEMA_WARN("Device is already initialized!!!"); } if (&instance->config != input_config) + { instance->config = *input_config; + } FSemaHwResetAll(base_addr); /* 重置所有的锁 */ if (FSEMA_SUCCESS == ret) + { instance->is_ready = FT_COMPONENT_IS_READY; + } return ret; } @@ -127,7 +131,7 @@ FError FSemaCreateLocker(FSema *const instance, FSemaLocker *const locker) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } @@ -136,14 +140,14 @@ FError FSemaCreateLocker(FSema *const instance, FSemaLocker *const locker) /* 分配一把未创建的锁 */ if (NULL == instance->locker[locker_idx]) { - FSEMA_INFO("allocate locker %d", locker_idx); + FSEMA_INFO("Allocate locker %d.", locker_idx); break; } } if (locker_idx >= FSEMA_NUM_OF_LOCKER) { - FSEMA_ERROR("no locker available !!!"); + FSEMA_ERROR("No locker available !!!"); return FSEMA_ERR_NO_AVAILABLE_LOCKER; /* 所有的锁都已经分配创建 */ } @@ -176,7 +180,7 @@ FError FSemaTryLock(FSemaLocker *const locker, u32 owner, u32 try_times, FSemaRe if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } @@ -185,10 +189,14 @@ FError FSemaTryLock(FSemaLocker *const locker, u32 owner, u32 try_times, FSemaRe /* 尝试获取锁 */ lock_success = FSemaTryLockOnce(base_addr, locker->index); if (TRUE == lock_success) + { break; + } if (relax_handler) + { relax_handler(instance); + } try_times--; } @@ -196,12 +204,12 @@ FError FSemaTryLock(FSemaLocker *const locker, u32 owner, u32 try_times, FSemaRe if (FALSE == lock_success) { ret = FSEMA_ERR_LOCK_TIMEOUT; - FSEMA_ERROR("locker-%d has been taken by owner 0x%x", locker->index, locker->owner); + FSEMA_ERROR("locker-%d has been taken by owner 0x%x.", locker->index, locker->owner); } else { locker->owner = owner; /* 记录当前locker的owner */ - FSEMA_INFO("locker-%d taken success by owner 0x%x", locker->index, owner); + FSEMA_INFO("locker-%d is taken successfully by owner 0x%x.", locker->index, owner); } return ret; @@ -224,7 +232,7 @@ FError FSemaUnlock(FSemaLocker *const locker, u32 owner) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } @@ -263,7 +271,7 @@ FError FSemaUnlockAll(FSema *const instance) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } @@ -295,17 +303,17 @@ FError FSemaDeleteLocker(FSemaLocker *const locker) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } if (TRUE == FSemaHwGetStatus(base_addr, locker_idx)) { - FSEMA_WARN("caution, locker-%d has been taken by 0x%x !!!", + FSEMA_WARN("Caution, locker-%d has been taken by 0x%x !!!", locker_idx, locker->owner); } - FASSERT_MSG((instance->locker[locker_idx] == locker), "invalid locker index %d", locker_idx); + FASSERT_MSG((instance->locker[locker_idx] == locker), "invalid locker index %d.", locker_idx); FSemaWriteReg(base_addr, FSEMA_RLOCK_X_REG_OFFSET(locker->index), FSEMA_RLOCK_X_UNLOCK); /* 写0解锁信号量 */ @@ -329,7 +337,7 @@ boolean FSemaIsLocked(FSemaLocker *locker) if (FT_COMPONENT_IS_READY != instance->is_ready) { - FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr); + FSEMA_ERROR("Device@%p is not yet inited !!!", instance->config.base_addr); return FSEMA_ERR_NOT_INIT; } diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.h b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.h index 361234d1e5..986fffe132 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.h +++ b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore.h @@ -14,7 +14,7 @@ * FilePath: fsemaphore.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:35 - * Description:  This files is for semaphore user api definition + * Description:  This file is for semaphore user api definition * * Modify History: * Ver   Who        Date         Changes @@ -23,18 +23,19 @@ */ -#ifndef DRIVERS_IPC_FSEMAPHORE_H -#define DRIVERS_IPC_FSEMAPHORE_H +#ifndef FSEMAPHORE_H +#define FSEMAPHORE_H + +/***************************** Include Files *********************************/ + +#include "ftypes.h" +#include "ferror_code.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "ftypes.h" -#include "ferror_code.h" - /************************** Constant Definitions *****************************/ #define FSEMA_NUM_OF_LOCKER 32U #define FSEMA_OWNER_NONE 0U diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_g.c b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_g.c index 1ee775f7d1..c715ce1630 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_g.c +++ b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_g.c @@ -14,7 +14,7 @@ * FilePath: fsemaphore_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:09 - * Description:  This files is for semaphore static variables + * Description:  This file is for semaphore static variables * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_hw.h b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_hw.h index d70e93ebf5..1266a4fdaf 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_hw.h @@ -14,7 +14,7 @@ * FilePath: fsemaphore_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for semaphore register definition + * Description:  This file is for semaphore register definition * * Modify History: * Ver   Who        Date         Changes @@ -23,13 +23,8 @@ */ -#ifndef DRIVERS_IPC_FSEMAPHORE_HW_H -#define DRIVERS_IPC_FSEMAPHORE_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FSEMAPHORE_HW_H +#define FSEMAPHORE_HW_H /***************************** Include Files *********************************/ #include "fparameters.h" @@ -38,6 +33,11 @@ extern "C" #include "fassert.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /** @name Register Map * diff --git a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_sinit.c b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_sinit.c index 4e52d6fd1a..2563566b69 100644 --- a/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/ipc/fsemaphore/fsemaphore_sinit.c @@ -14,7 +14,7 @@ * FilePath: fsemaphore_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:15 - * Description:  This files is for semaphore static init + * Description:  This file is for semaphore static init * * Modify History: * Ver   Who        Date         Changes diff --git a/bsp/phytium/libraries/standalone/drivers/media/Kconfig b/bsp/phytium/libraries/standalone/drivers/media/Kconfig new file mode 100644 index 0000000000..cec2cf2e3d --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/Kconfig @@ -0,0 +1,22 @@ + + +menu "Media Configuration" + config ENABLE_FDC_DP + bool + prompt "USE FMEDIA" + default n + help + Select fdcdp driver component + + config ENABLE_FDC_DP_USE_LIB + bool + prompt "USE FMEDIA LIB TO LINK" + default n + help + Select fdcdp driver component + + +endmenu + + + diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc.h new file mode 100644 index 0000000000..80452f2349 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc.h @@ -0,0 +1,359 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdc.h + * Date: 2022-09-05 22:53:24 + * LastEditTime: 2022-09-05 22:53:24 + * Description: This file is for defining the dc config and function + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDC_H +#define FDC_H +/***************************** Include Files *********************************/ + +#include "ftypes.h" + +#include "fdcdp_param.h" + +/************************** Constant Definitions *****************************/ +#define FMEDIA_DC_SUCCESS FT_SUCCESS + +/************************** Constant Definitions *****************************/ + +#define FDC_FALSE 0 +#define FDC_TRUE 1 +#define FDCDP_PATH_NUM 2 + +#define FDC_GOP_MAX_MODENUM 11 + +#define FDC_PCCON_BUFFER_SIZE (1 * 1024 * 1024) + +typedef enum +{ + FDC_MULTI_MODE_CLONE = 0, + FDC_MULTI_MODE_HORIZONTAL, + FDC_MULTI_MODE_VERTICAL, + + FDC_MULTI_MODE +} FDcMultiMode; + +typedef enum +{ + FDC_ROT_0 = 0, + FDC_FLIP_X, + FDC_FLIP_Y, + FDC_FLIP_XY, + FDC_ROT_90, + FDC_ROT_180, + FDC_ROT_270, +} FDcRotType; + +typedef enum +{ + FDC_RESET_CORE = 0, + FDC_RESET_AXI, + FDC_RESET_AHB, +} FDcRestType; + +typedef enum +{ + FDC_PHY_DPI, + FDC_PHY_DP, +} FDcPhyOutPutType; +/* + * Frame buffer mode. + * Used in ConfFramebufferSetConfig() + */ +typedef enum +{ + FDC_PHY_LINEAR, + FDC_PHY_TIILED, +} FDcPhyTilingType; + +typedef enum +{ + FDC_FORMAT_X4R4G4B4 = 0x0, + FDC_FORMAT_A4R4G4B4, + FDC_FORMAT_X1R5G5B5, + FDC_FORMAT_A1R5G5B5, + FDC_FORMAT_R5G6B5, + FDC_FORMAT_X8R8G8B8, + FDC_FORMAT_A8R8G8B8, + FDC_FORMAT_YUY2, + FDC_FORMAT_UYVY, + FDC_FORMAT_INDEX8, + FDC_FORMAT_MONOCHROME, + FDC_FORMAT_YV12 = 0x0F, + FDC_FORMAT_A8, + FDC_FORMAT_NV12, + FDC_FORMAT_NV16, + FDC_FORMAT_RG16, + FDC_FORMAT_RB, + FDC_FORMAT_NV12_10BIT, + FDC_FORMAT_A2R10G10B10, + FDC_FORMAT_NV16_10BIT, + FDC_FORMAT_INDEX1, + FDC_FORMAT_INDEX2, + FDC_FORMAT_INDEX4, + FDC_FORMAT_P010 +} FDcVideoFormate; + +typedef enum +{ + FDC_OUTPUT_RGB565 = 0, + FDC_OUTPUT_RGB666, + FDC_OUTPUT_RGB888, + FDC_OUTPUT_RGB1010, +} FDcOutputColor; + +/**************************** Type Definitions *******************************/ + +typedef struct +{ + u32 instance_id; /* dc id */ + uintptr dcch_baseaddr; /* DC channel register address*/ + uintptr dcctrl_baseaddr; /* DC control register address */ + u32 irq_num; /* Device intrrupt id */ +} FDcConfig; + +typedef struct +{ + u32 visble_line; /* Visible Number of lines */ + u32 total_line; /* Total Number of lines. */ + u32 sync_start; /* Start of sync pulse. */ + u32 sync_end; /* End of sync pulse. */ + boolean sync_polarity; /* Polarity of the sync pulse.1 - positive , 0 - negative. */ +} FDcDisplayTimmingConfig; + +typedef struct +{ + FDcDisplayTimmingConfig horizontal; + FDcDisplayTimmingConfig vertical; + boolean timing_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcSyncParameter; /* horizontal and vertical timing parameter */ + +typedef struct +{ + u32 color_format; /* color format. */ + uintptr framebuffer_p; /* Starting address of the frame buffer. */ + u32 tiling_mode; /* tile mode */ + u32 yuv_type; /* unused , reserved */ + u32 stride; /* memory image line span , --- FDcWidthToStride */ + u32 a_stride; /* Processing is consistent with memory image line spans */ + boolean fb_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcDisplayFramebuffer; + +typedef struct +{ + boolean data_enable_polarity; /* Data Enable polarity , 1 - positive , 0 - negative. */ + boolean data_polarity; /* Data polarity , 1 - positive , 0 - negative. */ + boolean clock_polarity; /* Clock polarity , 1 - positive , 0 - negative. */ + boolean panel_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcDisplayPanel; + +typedef struct +{ +#define gama_index_max 256 + boolean gamma_enable; /*enable the gamma*/ + u32 gamma; + boolean gamma_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcDisplayGamma; + +typedef struct +{ + boolean enable; + u32 red_channel; /* red channel of dither*/ + u32 green_channel; /* red green of dither*/ + u32 blue_channel; /* blue channel of dither*/ + u32 table_low; /* the low level of dither*/ + u32 table_high; /* the high level of dither*/ + boolean dither_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcDisplayDither; + +typedef struct +{ + boolean outputenable; + u32 output_type; /* Output format , 0 - DPI mode , 1 - DP mode. */ + + /* dp mode */ + u32 dp_format; /* DC output color format, 0 - 565 , 1 - RGB666 , 2 - RGB888 , 3 - RGB101010. */ + + /* dpi mode */ + u32 dpi_type; /* the dc output mode */ + u32 dpi_format; /* DC output type , 1 - RGB666 , 2 - RGB888 , 3 - RGB101010. */ + u32 dpi_actime; /* DC active time*/ + u32 dpi_period[2]; /*the period time of dc */ + u32 dpi_eor_assert[2]; /* params, unused*/ + u32 dpi_cs_assert[2]; /* params, unused*/ + boolean dpi_polarity; /*the polarity of output data */ + boolean output_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ + +} FDcDisplayDpMode; + +typedef struct +{ + boolean enable; + u64 phys_addr; /* Address of the cursor shape. */ + u32 type; /* Cursor type , 0 - disable , 1 - mask mode , 2 - argb mode. */ + u32 x; /* X location of cursor's hotspot. */ + u32 y; /* Y location of cursor's hotspot. */ + u32 hot_x; /* Vertical offset to cursor hotspot. */ + u32 hot_y; /* Horizontal offset to cursor hotspot. */ + u32 bg_color; /* The background color for Masked cursors . Format is ARGB8888. */ + u32 fg_color; /* The foreground color for Masked cursors . Format is ARGB8888. */ + boolean cursor_dirty; /* if value is FDC_TRUE , when using the FDcCoreCommit interface, the parameters will be updated */ +} FDcDisplayCursor; + +typedef struct +{ + u32 y_address; + u32 u_address; + u32 v_address; + u32 u_stride; + u32 v_stride; + u32 rot_angle; + u32 alpha_mode; + u32 alpha_value; + /* Original size in pixel before rotation and scale. */ + u32 width; + u32 height; + u32 tile_mode; + u32 scale; + u32 scale_factorx; + u32 scale_factory; + u32 filter_tap; + u32 horizontal_filtertap; +#define HOR_KERNEL_MAX 128 + u32 horkernel[128]; +#define VER_KERNEL_MAX 128 + u32 verkernel[128]; + u32 swizzle; + u32 uv_swizzle; + u32 color_key; + u32 colorkey_high; + u32 bg_color; + u32 trans_parency; + u32 clear_fb; + u32 clear_value; + u32 initial_offsetx; + u32 initial_offsety; + u32 compressed; +} FDcDisplayVideoMode; + +typedef struct +{ + u32 pixelclock; /* the pixelclock of dc */ + u32 horpixel; /*horizontal pixel */ + u32 verpixel; /*vertical pixel */ + FDcSyncParameter FDcSyncParameter; +} FDcDtdTable; + +typedef struct +{ + FDcDtdTable dtd_table; /*the table of dtd params*/ + FDcSyncParameter sync_parameter[FDC_GOP_MAX_MODENUM]; + FDcDisplayFramebuffer framebuffer; + FDcDisplayPanel panel; + FDcDisplayGamma gamma; + FDcDisplayDither dither; + FDcDisplayDpMode dp_mode; + FDcDisplayVideoMode video_mode; /*the params of video*/ + FDcDisplayCursor cursor; +} FDcCurrentConfig; + +typedef struct +{ + FDcCurrentConfig fdc_current_config; + FDcConfig config; + u32 multimode; /* The display mode of the device , including clone, horizontal and vertical display*/ + +} FDcCtrl; + +/************************** Function Prototypes ******************************/ + +/*Initialization of dc configuration parameter */ +FError FDcConfigInit(FDcCtrl *instance_p, FDcDpDisplaySetting *gop_mode, u32 mode_id); + +/* config to ddr */ + +/*config the panel data of core data */ +void FDcPanelSetConfig(FDcCtrl *instance_p, boolean data_enable_polarity, boolean data_polarity, boolean clock_Polarity); + +/* set the horizontal timing parameter */ +void FDcDisplaySetHorizontal(FDcCtrl *instance_p, u32 mode_id, u32 total_pixels, u32 line_pixels, u32 hsync_start, u32 hsync_end, boolean hsync_polarity); + +/* set the vertical timing parameter */ +void FDcDisplaySetVertical(FDcCtrl *instance_p, u32 mode_id, u32 line_pixels, u32 total_pixels, u32 vsync_start, u32 vsync_end, boolean vsync_polarity); +/* select core data about dc output mode , DP mode or DPI mode */ +void FDcOutputSelect(FDcCtrl *instance_p, FDcPhyOutPutType output_type); + +/* config core data about dc output formort , DP mode or DPI mode */ +void FDcOutputDpformat(FDcCtrl *instance_p, FDcOutputColor format); + +/* config tilemode and color format of vedio */ +void FDcTilemodeSetConfig(FDcCtrl *instance_p, FDcVideoFormate format, FDcPhyTilingType tiling); + +/* core data config about framebuffer parameter */ +void FDcFramebufferSetFramebuffer(FDcCtrl *instance_p, FDcDisplayVideoMode *fdc_video_params); + +/* config core data about dither enable */ +void FDcDitherEnable(FDcCtrl *instance_p, boolean enable); + +/* update config */ + +/* enable core data about gamma */ +void FDcGammaEnable(FDcCtrl *instance_p, boolean enable); + +/* config register about all dc parameters include video framebuffer address and stride +the main function interface to set the dc parameters*/ +FError FDcCoreCommit(FDcCtrl *instance_p, u32 mode_id); + +/* direct update config */ + +/* commit display configuration about timing parameter*/ +void FDcDisplayCommit(FDcCtrl *instance_p, u32 mode_id); + +/* config register about dc output mode, DP or DPI */ +void FDcOutputCommit(FDcCtrl *instance_p); + +/* config register about panel */ +void FDcPanelCommit(FDcCtrl *instance_p); + +/* config register about cursor parameter */ +void FDcCursorCommit(FDcCtrl *instance_p); + +/* cursor setting */ + +/* enable the cursor */ +void FDcCursorEnable(FDcCtrl *instance_p, boolean enable); + +/* config core data about cursor hotspot */ +void FDcCursorSetHotspot(FDcCtrl *instance_p, uintptr x, uintptr y); + +/* config core data about location of the cursor on the owning display */ +void FDcCursorSetPos(FDcCtrl *instance_p, uintptr x, uintptr y); + +/* Config register about vedio parameter and framebuffer */ +void FDcFramebufferCommit(FDcCtrl *instance_p); + +/* common setting */ + +/* according to the width, calculate the stride */ +FError FDcWidthToStride(u32 width, u32 color_depth, u32 multimode); + +#endif diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_common_hw.h similarity index 51% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.h rename to bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_common_hw.h index 513332661b..ca387a920b 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.h +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_common_hw.h @@ -11,31 +11,32 @@ * See the Phytium Public License for more details. * * - * FilePath: fpsci.h - * Date: 2022-02-10 14:53:41 - * LastEditTime: 2022-02-17 17:34:06 - * Description:  This files is for + * FilePath: fdc_hw.h + * Date: 2022-09-10 14:53:42 + * LastEditTime: 2022-09-18 08:29:10 + * Description: This file is for Handling the hardware register and + * providing some function interface * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version */ +#ifndef FDC_COMMON_HW_H +#define FDC_COMMON_HW_H - -#ifndef BSP_ARCH_AARMV8_AARCH64_PSCI_H -#define BSP_ARCH_AARMV8_AARCH64_PSCI_H - -#ifdef __cplusplus -extern "C" -{ -#endif +/***************************** Include Files *********************************/ #include "ftypes.h" #include "ferror_code.h" -void PsciCpuReset(void); -FError PsciCpuOn(s32 cpu_id_mask, uintptr bootaddr); +#include "fdc.h" -#ifdef __cplusplus -} +/*set pixel clock in kilohertz unit by configurating register */ +FError FDcReqChangePixel(FDcCtrl *instance_p, u32 pixel_clk); + +/* soft reset DC by configurating register */ +void FDcHwFramebufferReset(FDcCtrl *instance_p, u32 num, FDcRestType type); + +/* Get mode number by width and height */ +FError FDcResToModeNum(u32 width, u32 height); #endif -#endif // !BSP_ARCH_AARMV8_AARCH64_PSCI_H \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_hw.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_hw.h new file mode 100644 index 0000000000..dfae755c13 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdc_hw.h @@ -0,0 +1,200 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdc_hw.h + * Date: 2022-09-10 14:53:42 + * LastEditTime: 2022-09-18 08:29:10 + * Description:  This file is for providing some hardware register and function definition + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDC_HW_H +#define FDC_HW_H + +/***************************** Include Files *********************************/ + +#include "ftypes.h" +#include "ferror_code.h" +#include "fkernel.h" + +/**************************** Type Definitions *******************************/ + +#define FDC_READ_REG32(addr, reg_offset) FtIn32((addr) + (u32)(reg_offset)) +#define FDC_WRITE_REG32(addr, reg_value) FtOut32(addr, (u32)(reg_value)) +#define FDC_PHY_ALIGN(data, Offset) ((data + Offset - 1) & ~(Offset - 1)) + +/************************** Constant Definitions *****************************/ + +/* +AHB Byte Address +DC Ctrl Register*/ +#define FDC_AQ_HI_CLOCK_CONTROL 0x0000 +#define FDC_AQ_HI_IDLE 0x0004 +#define FDC_AQ_AXI_STATUS 0x000C +#define FDC_AQ_INTR_ENBL 0x0014 +#define FDC_AQ_INTR_ACKNOWLEDGE 0x0010 +#define FDC_GC_TOTAL_READS 0x0040 +#define FDC_GC_TOTAL_CYCLES 0x0078 +#define FDC_CTRL_CH0_PIXEL_CLOCK 0x00F0 +#define FDC_CTRL_CH1_PIXEL_CLOCK 0x00F4 + +/* Each Dc Core Register */ +#define FDC_GCREG_FRAMEBUFFERADDR_LOW 0x400 +#define FDC_GCREG_FRAMEBUFFERADDR_HIGH 0x404 +#define FDC_GCREG_FRAMEBUFFERSTRIDE0 0x408 +#define FDC_GCREG_DISPLAYDITHERCONFIG0 0x410 +#define FDC_GCREG_PANEL_CONFIG0 0x418 +#define FDC_GCREG_DISPLAY_DITHERTABLELOW0 0x420 +#define FDC_GCREG_DISPLAY_DITHERTABLEHIGH0 0x428 +#define FDC_GCREG_HDISPLAY0 0x430 +#define FDC_GCREG_HSYNC0 0x438 +#define FDC_GCREG_VDISPLAY0 0x440 +#define FDC_GCREG_VSYNC0 0x448 +#define FDC_GCREG_DISPLAY_CURLOCATION0 0x450 +#define FDC_GCREG_GAMMAINDEX0 0x458 +#define FDC_GCREG_GAMMADATA0 0x460 +#define FDC_GCREG_CURSOR_CONFIG 0x468 +#define FDC_GCREG_CURSOR_ADDR_LOW 0x46C +#define FDC_GCREG_CURSOR_ADDR_HIGH 0x490 +#define FDC_GCREG_CURSOR_LOCATION 0x470 +#define FDC_GCREG_CURSOR_BACKGROUND 0x474 +#define FDC_GCREG_CURSOR_FORGEGROUND 0x478 +#define FDC_GCREG_DISPLAY_INTR 0x47C +#define FDC_GCREG_DISPLAY_INTR_ENABLE 0x480 +#define FDC_GCREG_CURSOR_MODCLKGATECONTROL 0x484 +#define FDC_GCREG_DEBUGCOUNTER_SELECT0 0x4D0 +#define FDC_GCREG_DEBUGCOUNTER_VALUE0 0x4D8 +#define FDC_GCREG_FRAMEBUFFER_COLORKEY0 0x508 +#define FDC_GCREG_FRAMEBUFFER_COLORKEYHIGH0 0x510 +#define FDC_GCREG_FRAMEBUFFER_CONFIG0 0x518 +#define FDC_GCREG_FRAMEBUFFER_SCALECONFIG0 0x520 +#define FDC_GCREG_FRAMEBUFFER_BGCOLOR0 0x528 +#define FDC_GCREG_FRAMEBUFFER_UPPLANARADDR_LOW 0x530 +#define FDC_GCREG_FRAMEBUFFER_UPPLANARADDR_HIGH 0x534 +#define FDC_GCREG_FRAMEBUFFER_VPPLANARADDR_LOW 0x538 +#define FDC_GCREG_FRAMEBUFFER_VPPLANARADDR_HIGH 0x53C +#define FDC_GCREG_FRAMEBUFFER_USTRIDE0 0x800 +#define FDC_GCREG_FRAMEBUFFER_VSTRIDE0 0x808 +#define FDC_GCREG_FRAMEBUFFER_SIZE0 0x810 +#define FDC_GCREG_FRAMEBUFFER_SCALEFACTORX0 0x828 +#define FDC_GCREG_FRAMEBUFFER_SCALEFACTORY0 0x830 +#define FDC_GCREG_HORIFILTERKERNEL_INDEX0 0x838 +#define FDC_GCREG_HORI_FILTERKERNEL0 0xA00 +#define FDC_GCREG_VERTI_FILTERKERNEL_INDEX0 0xA08 +#define FDC_GCREG_VERTI_FILTERKERNEL0 0xA10 +#define FDC_GCREG_FRAMEBUFFER_CLEARVALUE0 0xA18 +#define FDC_GCREG_FRAMEBUFFER_INITOFFSET0 0xA20 +#define FDC_GCREG_MODCLKGATE_CONTROL0 0xA28 +#define FDC_GCREG_READ_OT 0xCC8 +#define FDC_GCREG_DPCONFIG0 0xCD0 + +/* FDC_GCREG_FRAMEBUFFER_SIZE0 */ +#define FDC_GCREG_FRAMEBUFFER_SIZE0_HEIGHT_SET(x) SET_REG32_BITS((x), 29, 15) /* the height of window size of the framebuffer in memory - in pixels*/ +#define FDC_GCREG_FRAMEBUFFER_SIZE0_WIDTH_SET(x) SET_REG32_BITS((x), 14, 0) /* the width of window size of the framebuffer in memory -in pixels*/ +/* FDC_GCREG_FRAMEBUFFER_SCALECONFIG0 */ +#define FDC_GCREG_FRAMEBUFFER_SCALECONFIG0_H_FILTER_TAP_SET(x) SET_REG32_BITS((x), 7, 4) /* the number of horizontal filter tap*/ +#define FDC_GCREG_FRAMEBUFFER_SCALECONFIG0_V_FILTER_TAP_SET(x) SET_REG32_BITS((x), 3, 0) /* the number of vertial filter tap*/ +/* FDC_GCREG_FRAMEBUFFER_INITOFFSET0 */ +#define FDC_GCREG_FRAMEBUFFER_INITOFFSET0_Y_SET(x) SET_REG32_BITS((x), 31, 16) /* Y location of the framebuffer scalar source offset register */ +#define FDC_GCREG_FRAMEBUFFER_INITOFFSET0_X_SET(x) SET_REG32_BITS((x), 15, 0) /* X location of the framebuffer scalar source offset register */ + +/* FDC_GCREG_FRAMEBUFFER_CONFIG0 */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_FORMAT_SET(x) SET_REG32_BITS((x), 31, 26) /* framebuffer configuration register can see the struct in the VIDEO_FORMAT*/ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_UV_SWIZZLE BIT(25) /* UV swizzle */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_SWIZZLE_SET(x) SET_REG32_BITS((x), 24, 23) /* swizzle mode ,0:ARGB, 1:RGBA, 2:ABGR, 3:BGRA */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_SCALE BIT(22) /* scale of config, 0:disable, 1:enable */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_TILE_MODE_SET(x) SET_REG32_BITS((x), 21, 17) /* set the tilemode */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_YUV_SET(x) SET_REG32_BITS((x), 16, 14) /* yuv standard, 1: 709*bt709, 3:2020*bt2020*/ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_ROT_ANGLE_SET(x) SET_REG32_BITS((x), 13, 11) /* the angle of the rot, 0:roto, 1:flip_x, 2:flip_y, 3:flip_xy, 5:rot180 */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_TRANSPARENCY_SET(x) SET_REG32_BITS((x), 10, 9) /* transparency of framebuffer */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_CLEAR BIT(8) /* the source of the pixel value ,enable :from dcregframebufferclear value,disable: from memory */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_FLIP_PROGRESS BIT(6) /* 0:NO, 1:YES, related to the framebuffer address and the vblank */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_UNDERFLOW BIT(5) /* 0:NO, 1:YES, related to the display fifo underflows */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_RESET BIT(4) /* enable reset for the display controller */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_VALID BIT(3) /* decided if you can copy a set of registers ar the next vblank */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_GAMMA BIT(2) /* gamma is enabled,rgb channel will be routed */ +#define FDC_GCREG_FRAMEBUFFER_CONFIG0_OUTPUT BIT(0) /* output is enabled ,pixels will be displayed */ + +/* FDC_GCREG_CURSOR_CONFIG */ +#define FDC_GCREG_CURSOR_CONFIG_HOT_SPOT_X_SET(x) SET_REG32_BITS((x), 20, 16) /* horizontal offset to the cursor hotspot */ +#define FDC_GCREG_CURSOR_CONFIG_HOT_SPOT_Y_SET(x) SET_REG32_BITS((x), 12, 8) /* vertical offset to the cursor hotspot */ +#define FDC_GCREG_CURSOR_CONFIG_HOT_FORMAT_SET(x) SET_REG32_BITS((x), 1, 0) /* format of the cursor,0: disabled, 1:masked, 2:ARGB888 \ + \ \ +/* FDC_GCREG_CURSOR_LOCATION */ +#define FDC_GCREG_CURSOR_LOCATION_Y_SET(x) SET_REG32_BITS((x), 31, 16) /* Y location of cursor hotspot */ +#define FDC_GCREG_CURSOR_LOCATION_X_SET(x) SET_REG32_BITS((x), 15, 0) /* X location of cursor hotspot */ + +/* FDC_GCREG_HSYNC0 */ +#define FDC_GCREG_HSYNC0_POLARITY BIT(31) /* polarity of the horizontal sync pulse */ +#define FDC_GCREG_HSYNC0_PULSE BIT(30) /* horizontal sync pulse control */ +#define FDC_GCREG_HSYNC0_END_SET(x) SET_REG32_BITS((x), 29, 15) /* end of horizontal sync pulse */ +#define FDC_GCREG_HSYNC0_START_SET(x) SET_REG32_BITS((x), 14, 0) /* start of the horizontal sync pulse */ + +/* FDC_GCREG_VSYNC0 */ +#define FDC_GCREG_VSYNC0_POLARITY BIT(31) /* polarity of the vertical sync pulse */ +#define FDC_GCREG_VSYNC0_PULSE BIT(30) /* vertical sync pulse control */ +#define FDC_GCREG_VSYNC0_END_SET(x) SET_REG32_BITS((x), 29, 15) /* end of vertical sync pulse */ +#define FDC_GCREG_VSYNC0_START_SET(x) SET_REG32_BITS((x), 14, 0) /* start of the vertical sync pulse */ + +/* FDC_GCREG_VDISPLAY */ +#define FDC_GCREG_VDISPLAY_TOTAL_SET(x) SET_REG32_BITS((x), 30, 16) /* total number of vertical pixels */ +#define FDC_GCREG_VDISPLAY_DISPLAY_END_SET(x) SET_REG32_BITS((x), 14, 0) /* visible number of vertical pixels */ + +/* FDC_GCREG_HDISPLAY0 */ +#define FDC_GCREG_HDISPLAY0_TOTAL_SET(x) SET_REG32_BITS((x), 30, 16) /* total number of horizontal pixels */ +#define FDC_GCREG_HDISPLAY0_DISPLAY_END_SET(x) SET_REG32_BITS((x), 14, 0) /* visible number of vertical pixels */ + +/* FDC_GCREG_PANEL_CONFIG0 */ +#define FDC_GCREG_PANEL_CONFIG0_DATA_CLOCK_POLATITY BIT(9) /* data clock polarity*/ +#define FDC_GCREG_PANEL_CONFIG0_DATA_CLOCK_ENABLE BIT(8) /* data enable enable */ +#define FDC_GCREG_PANEL_CONFIG0_DATA_POLARITY BIT(5) /* data enable polarity */ +#define FDC_GCREG_PANEL_CONFIG0_DATA_ENABLE BIT(4) /* data enable */ +#define FDC_GCREG_PANEL_CONFIG0_DATA_DE_POLATITY BIT(1) /* data enable polarity */ +#define FDC_GCREG_PANEL_CONFIG0_DATA_DE BIT(0) /* data enable enabled/disabled */ + +/* FDC_GCREG_DISPLAYDITHERCONFIG0 */ +#define FDC_GCREG_DISPLAYDITHERCONFIG0_ENABLE BIT(31) + +/* FDC_GCREG_GAMMAINDEX0 */ +#define FDC_GCREG_GAMMAINDEX0_INDEX_SET(x) SET_REG32_BITS((x), 7, 0) /*gamma table index register ,index into gamma table */ + +/* FDC_GCREG_GAMMADATA0 */ +#define FDC_GCREG_GAMMADATA0_RED_SET(x) SET_REG32_BITS((x), 29, 20) /* red translation value */ +#define FDC_GCREG_GAMMADATA0_GREEN_SET(x) SET_REG32_BITS((x), 19, 10) /* green translation value */ +#define FDC_GCREG_GAMMADATA0_BLUE_SET(x) SET_REG32_BITS((x), 9, 0) /* blue translation value */ + +/*FDC_GCREG_DISPLAY_INTR_ENABLE */ +#define FDC_GCREG_DISPLAY_INTR_ENABLE_DC1_UNDERFLOW BIT(5) /* dc1 underflow interrupt enable */ +#define FDC_GCREG_DISPLAY_INTR_ENABLE_DC1_INTR BIT(4) /* dc1 frame complete interrupt enable */ +#define FDC_GCREG_DISPLAY_INTR_ENABLE_DC0_UNDERFLOW BIT(1) /* dc0 underflow interrupt enable */ +#define FDC_GCREG_DISPLAY_INTR_ENABLE_DC0_INTR BIT(0) /* dc0 frame complete interrupt enable */ + +/**************************************************************************************/ + +/* write the data to the channel of DcDp */ +void FDcChannelRegWrite(uintptr addr, uintptr offset, u32 data); + +/* read the data from the channel of DcDp */ +FError FDcChannelRegRead(uintptr addr, uintptr offset); + +/* write Dc control register */ +void FDcCtrlRegWrite(uintptr addr, uintptr offset, u32 data); + +/* read Dc control register */ +FError FDcCtrlRegRead(uintptr addr, uintptr offset); + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp.h new file mode 100644 index 0000000000..0afce2cf4a --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp.h @@ -0,0 +1,115 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdcdp.h + * Date: 2022-09-05 17:28:55 + * LastEditTime: 2022-09-05 17:28:55 + * Description: This file is for providing the general config of dc and dp + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------ -------- -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDCDP_H +#define FDCDP_H + +#include "fdc.h" +#include "fdp.h" +#include "ftypes.h" +#include "fparameters.h" +#include "fdcdp_param.h" + +#define FDP_DISPLAY_REFRESH_RATE_60 60 +#define FDP_DISPLAY_REFRESH_RATE_59 59 +#define FDP_DISPLAY_REFRESH_RATE_40 40 +#define FDP_DISPLAY_REFRESH_RATE_30 30 + +#define FDP_DISPLAY_COLOR_DEPTH_32 32 +#define FDP_DISPLAY_COLOR_DEPTH_16 16 + +#define FDP_EDP_LIGHTTURNON_CMD 101 +#define FDP_EDP_LIGHTTURNOFF_CMD 102 +#define FDP_EDP_OPENPWR_CMD 103 +#define FDP_EDP_POWEROFF_CMD 104 +#define FDP_LIGHT_ADJUST_CMD 0x1 +#define FDP_CMD_STATE_OFFSET 28 +#define FDP_LIGHT_VALUE_OFFSET 21 + +#define FDP_ALL_CHANNEL 0xffffffff + +#define FDP_MRAM_SIZE (3840 * 2160 * 4) + + +typedef enum +{ + FDCDP_HPD_IRQ_CONNECTED = 0, /* hpd 中断 */ + FDCDP_HPD_IRQ_DISCONNECTED, + FDCDP_AUX_REPLY_TIMEOUT, + FDCDP_AUX_REPLY_ERROR, + + FDCDP_INTR_MAX_NUM +} FDcDpIntrEventType; + +typedef void (*FMediaIntrHandler)(void *param, u32 index); + +typedef struct +{ + FDcDpIntrEventType type; /* data */ + FMediaIntrHandler handler; + void *param; +} FMediaIntrConfig; + +typedef struct +{ + /* fdc instace object */ + FDcCtrl dc_instance_p[FDCDP_INSTANCE_NUM]; + /* fdp instace object */ + FDpCtrl dp_instance_p[FDCDP_INSTANCE_NUM]; + /* user config */ + /* resolution */ + /* color depth */ + FDcDpDisplaySetting display_setting[FDCDP_DISPLAY_ID_MAX_NUM]; + /* gamma parameter */ + /* .... */ + /* uintptr fb_p[FDCDP_INSTANCE_NUM];*/ + u32 is_ready; /* Device is ininitialized and ready*/ + FMediaIntrConfig intr_event[FDCDP_INTR_MAX_NUM]; + + void *args; + u32 connect_flg[FDCDP_INSTANCE_NUM]; + u32 connect_changed_flg[FDCDP_INSTANCE_NUM]; +} FDcDp; + +const FDpConfig *FDpLookupConfig(u32 instance_id); +const FDcConfig *FDcLookupConfig(u32 instance_id); +/*get the default config*/ +FError FDcDpGetDefaultConfig(FDcDp *instance_p, u32 channel_num); + +/*register the interrupt*/ +void FDcDpRegisterHandler(FDcDp *instance_p, FMediaIntrConfig *intr_event_p); + +/*the interrupt handler*/ +void FDcDpInterruptHandler(s32 vector, void *args); + +/*enable the interrupt*/ +void FDcDpIrqEnable(FDcDp *instance_p, FDcDpIntrEventType intr_event_p); + +/* init the DcDp */ +FError FDcDpInitial(FDcDp *instance_p, u32 channel_num, u32 mode_id,u32 multi_mode); + +/*the basic params init*/ +FError FDcDpSetBasicParam(FDcDp *instance_p, u32 channel_num, u32 mode_id); + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_multi_display.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_multi_display.h new file mode 100644 index 0000000000..95893b121d --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_multi_display.h @@ -0,0 +1,44 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdcdp_multi_display.h + * Date: 2023-02-05 18:27:47 + * LastEditTime: 2023-02-10 11:02:47 + * Description: This file is for defining the dp multidisplay config + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------ -------- -------------------------------------- + * 1.0 Wangzq 2023/02/10 Modify the format and establish the version + */ + +#ifndef FDCDP_MULTI_DISPLAY_H +#define FDCDP_MULTI_DISPLAY_H + +#include "ftypes.h" +#include "fparameters.h" + +typedef struct +{ + uintptr dp0_framebuffer;/* data */ + uintptr dp1_framebuffer; + u32 multi_mode; +} FDcDpFrameBuffer; + +/*set the frambbuffer of multidisplay*/ +FError FDcDpMultiDisplayFrameBufferSet(FDcDp *instance_p, u32 channel_num, u32 multi_mode); + +/*return the framebuffer*/ +FDcDpFrameBuffer *FDcDpGetFramebuffer(FDcDp *instance_p); + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_param.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_param.h new file mode 100644 index 0000000000..0a11d98183 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdcdp_param.h @@ -0,0 +1,66 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdcdp_param.h + * Date: 2022-09-05 17:31:47 + * LastEditTime: 2022-09-05 17:31:47 + * Description: This file is for providing some general config and params of dc and dp + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------ -------- -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDCDP_PARAM_H +#define FDCDP_PARAM_H + +#include "ftypes.h" +#include "fparameters.h" +#include "ferror_code.h" + +#define FMEDIA_DEFAULT_PARAM_ERR FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 1) +#define FMEDIA_ERR_PIXEL FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 3) +#define FMEDIA_ERR_EDID FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 4) +#define FMEDIA_ERR_HPD_DISCONNECTED FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 5) +#define FMEDIA_AUX_CONNECT_FAILED FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 7) +#define FMEDIA_TRAIN_TIME_ERR FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 8) +#define FMEDIA_REACH_MAX_VOLTAGE FT_MAKE_ERRCODE(ErrModBsp, ErrBspMEDIA, 9) + +typedef enum +{ + FDCDP_DISPLAY_ID_640_480 = 0, + FDCDP_DISPLAY_ID_800_600, + FDCDP_DISPLAY_ID_1024_768, + FDCDP_DISPLAY_ID_1280_720, + FDCDP_DISPLAY_ID_1366_768, + FDCDP_DISPLAY_ID_1920_1080, + FDCDP_DISPLAY_ID_1600_1200, + FDCDP_DISPLAY_ID_1280_800, + FDCDP_DISPLAY_ID_800_480, + FDCDP_DISPLAY_ID_1280_768, + FDCDP_DISPLAY_ID_1280_1024, + FDCDP_DISPLAY_ID_MAX_NUM + +} FDcDpDisplayId; +typedef struct +{ + u32 width; + u32 height; + u32 color_depth; /* value follow the DISPLAY_REFRESH_RATE_XX */ + u32 refresh_rate; /* value follow the DISPLAY_COLOR_DEPTH_XX */ + FDcDpDisplayId id; +} FDcDpDisplaySetting; + + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp.h new file mode 100644 index 0000000000..e6f6c21561 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp.h @@ -0,0 +1,190 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdp.h + * Date: 2022-09-08 14:53:42 + * LastEditTime: 2022-09-08 14:53:42 + * Description:  This file is for defining the dp config and function + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDP_H +#define FDP_H + +/***************************** Include Files *********************************/ + +#include "ftypes.h" +#include "fparameters_comm.h" +#include "fdcdp_param.h" +#include "fdc.h" + +/************************** Constant Definitions *****************************/ +#define FMEDIA_DP_SUCCESS FT_SUCCESS + +/************************** Constant Definitions *****************************/ + +#define FDP_HAS_TRAINED 1 +#define FDP_NOT_TRAINED 0 + +#define FDP_IS_HPD_ON 1 +#define FDP_IS_HPD_OFF 0 + +#define FDP_DIS_CONNECTED 1 +#define FDP_IS_CONNECTED 0 + +#define DP_GOP_MAX_MODENUM 11 + +typedef enum +{ + FDP_TRAINING_OFF = 0, + FDP_TRAINING_PATTERN_1, + FDP_TRAINING_PATTERN_2, + FDP_TRAINING_PATTERN_3 +} FDpTrainPattern; + +typedef enum +{ + FDP_BIT_DEPTH_6 = 0, + FDP_BIT_DEPTH_8, + FDP_BIT_DEPTH_10, + FDP_BIT_DEPTH_12, + FDP_BIT_DEPTH_16, + FDP_BIT_DEPTH_RESERVE +} FDpBitDepth; + +typedef enum +{ + FDP_PWR_MODE_D0 = 1, + FDP_PWR_MODE_D3 = 2, +} FDpPwrMode; /* the power state of dp_phy */ + +typedef struct +{ + u16 h_total; + u16 v_total; + boolean h_polarity; /*0 - active high , 1 - active low */ + boolean v_polarity; /*0 - active high , 1 - active low */ + u16 hs_width; /* Horizontal Sync Pulse Width in pixels. */ + u16 vs_width; /* Vertical Sync Pulse Width in lines. */ + u16 h_res; /* Horizontal Addressable video in lines. */ + u16 v_res; /* Vertical Addressable video in lines. */ + u16 h_start; /* Horizontal Blanking in pixels minus Horizontal Front Proch in pixels. */ + u16 v_start; /* Vertical Blanking in pixels minus Vertical Front Proch in pixels. */ + boolean h_user_polarity; /* Horizontal Sync Polarity. */ + boolean v_user_polarity; /* Vertical Sync Polarity. */ +} FDpSyncParameter; + +typedef struct +{ + u32 lane_count; /* The Number of lanes */ + u32 link_rate; /* Main link bandwidth. 162 - 1.62 270 - 2 540 - 810 - 8.1G */ + u8 bit_depth; /* Bit depth per color.For example , 6 means that Bit depth per color is 6 bits. */ + u8 color_rep_format; /* Color representation format. 0 - RGB , 1 - YCbCr 4:2:2 , 2 - YCbCr 4:4:4 , other - Reserved. */ + u8 clock_mode; /* clock_mode Clocking mode for the user data. 0 - asynchronous clock , 1 - synchronous clock. */ + u32 pixel_clock; /* pixel clock frequence in megahertz unit */ + u8 transfer_size; /* Transfer unit size.This parameter is usually 64. */ + u8 dis_type; /* index of video mode description structure */ +} FDpTransmissionConfig; + +typedef struct +{ + u32 dp_hpd_on; /* whether the dp is connected or not,1-connected,0-disconnected */ + u32 dp_trained; /* whether the dp has been trained or not,1-trained,0-distrained */ + u32 dp_connect; /* whether the source has been connected with sink or not ,1-trained,0-distrained */ +} FDpStatus; + +typedef struct +{ + u32 pixel_clock; /* the pixelclock of dp */ + u32 horPixel; /* horizontal pixel */ + u32 verPixel; /*vertical pixel */ + FDpSyncParameter sync_parameter[DP_GOP_MAX_MODENUM]; +} FDpDtdTable; + +typedef struct +{ + /* 设置参数 */ + FDpSyncParameter sync_parameter[DP_GOP_MAX_MODENUM]; + + FDpTransmissionConfig transmission_config; + + /* 当前状态 */ + FDpStatus status; + + u8 down_spread_enable; +#define dtd_list_max 4 + /* edid 缓冲数据 */ + FDpDtdTable dtd_table[dtd_list_max]; /* the max dtd num is 4 */ + +} FDpCurrentConfig; + +typedef struct +{ + u32 instance_id; + uintptr dp_channe_base_addr; + uintptr dp_phy_base_addr; + u32 irq_num; +} FDpConfig; + +typedef struct +{ + FDpCurrentConfig fdp_current_config; + FDpConfig config; +} FDpCtrl; + +/* dp init */ +FError FDpInit(FDcCtrl *dc_config, FDpCtrl *instance_p, FDcDpDisplaySetting *gop_mode, u32 mode_id); + +/* Initialization of dp configuration parameter */ +void FDpConfigInit(FDpCtrl *instance_p, FDcDpDisplaySetting *gop_mode); + +/* Dp connect to sink */ +FError FDpConnect(FDpCtrl *instance_p); + +/* Convert display resolution number to pixel clock frequence in megahertz unit */ +FError FDpDistypeToPixelClock(u8 mode_Num); + +/* sets the output of the transmitter core to the specified training pattern */ +void FDpConfigTxTrainingPattern(FDpCtrl *instance_p, FDpTrainPattern train_pattern); + +/* Force the transmitter core to use the alternate scrambler reset value */ +FError FDpConfigTraingPattern(FDpCtrl *instance_p); + +/* Config Main Stream Attributes.It is must to reset reset phy link after main + stream attributes configuration*/ +void FDpConfigMainStreamAttr(FDpCtrl *instance_p, FDpTransmissionConfig *fdp_trans_config, FDpSyncParameter *fdp_sync_config); + +/*Dp link training*/ + +/*Set sink device to D0(normal operation mode).*/ +FError FDpWakeUpSink(FDpCtrl *instance_p); + +FError FDpStartLinkTrain(FDpCtrl *instance_p, u8 lane_count, u32 link_rate); + +/* Get the status of all lanes */ +FError FDpTxGetTrainingStatus(FDpCtrl *instance_p, u8 *train_status); + +/* Determine whether retraining is needed at present.*/ +FError FDpSinkNeedReTrain(FDpCtrl *instance_p); /* not use*/ + +/*Check the overall training status of the specified nameber of lanes and Tps type.*/ +FError FDpCheckTrainingStatus(FDpCtrl *instance_p, u8 lane_count, u8 tpsn, u8 *value); + +/*Check the HPD status*/ +FError FDpCheckHpdStatus(FDpCtrl *instance_p); + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_aux.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_aux.h new file mode 100644 index 0000000000..276b0dafb4 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_aux.h @@ -0,0 +1,75 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdp_aux.h + * Date: 2022-09-08 14:53:42 + * LastEditTime: 2022-09-08 14:53:42 + * Description: This file is for Handling the aux register and + * providing some function interface + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ +#ifndef FDP_AUX_H +#define FDP_AUX_H +/***************************** Include Files *********************************/ + +#include "ftypes.h" + + +#define AUX_TIMEOUT 1 +#define AUX_CONNECT 0 +#define dtd_list_max 4 + +typedef struct +{ + u32 pixel_clock; + u32 hor_pixel; + u32 ver_pixel; + u32 hor_blanking; + u32 ver_blanking; + u32 hor_sync_front; + u32 ver_sync_front; + u32 hor_sync_width; + u32 ver_sync_width; + u8 hor_polarity; + u8 ver_polarity; +} Auxtable; +/*Initialize AUX channel include aux clock Initialization, dp timer Initialization + and interrupt mask. */ +FError FDpInitAux(FDpCtrl *instance_p); + +/*Wait util that an aux reply has been recieved*/ +FError FDpWaitAuxReply(FDpCtrl *instance_p); + +/*translate the dp information the dpsync*/ +FError FDpTimingToDpSync(Auxtable *instance_p, FDpSyncParameter *sync); + +/*translate the dc information the dcsync*/ +FError FDpTimingToDcSync(Auxtable *instance_p, FDcSyncParameter *sync); + +/* write phy register through aux channel.*/ +FError FDpSinkDpcdWrite(FDpCtrl *instance_p, u32 addr, u8 data); + +/* Read phy register through aux channel. */ +FError FDpSinkDpcdRead(FDpCtrl *instance_p, u32 addr, u8 *data); + +/* Get edid information form sink*/ +FError FDpGetEdid(FDpCtrl *instance_p, u8 *buffer); + +/*translate the edid information to the struct*/ +FError FDpParseDpEdidDtdList(u8 *buffer, Auxtable *list); + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_hw.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_hw.h new file mode 100644 index 0000000000..89fb78e6a7 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_hw.h @@ -0,0 +1,157 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdp_hw.h + * Date: 2022-09-08 14:53:42 + * LastEditTime: 2022-09-08 14:53:42 + * Description:  This file is for providing some hardware register and function definition + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ + +#ifndef FDP_HW_H +#define FDP_HW_H + +/***************************** Include Files *********************************/ + +#include "ftypes.h" +#include "fio.h" +#include "fkernel.h" + +/****************************************************************************/ +/** +* This macro writes the given register. +* @param base_addr is the base address of the device. +* @param reg_offset is the register offset to be written. +* @param data is the 32-bit value to write to the register. +* @return None. +* @note None. +*****************************************************************************/ +#define FDP_READ_REG32(addr, reg_offset) FtIn32((addr) + (u32)(reg_offset)) + +#define FDP_WRITE_REG32(addr, reg_value) FtOut32(addr, (u32)(reg_value)) + +#define FDC_PHY_ALIGN(data, Offset) ((data + Offset - 1) & ~(Offset - 1)) + +#define FDP_SETBIT(base_addr, reg_offset, data) FtSetBit32((base_addr) + (u32)(reg_offset), (u32)(data)) + +#define FDP_CLEARBIT(base_addr, reg_offset, data) FtClearBit32((base_addr) + (u32)(reg_offset), (u32)(data)) + +/* + TX Registers +*/ +#define FDPTX_LINK_BW_SET 0x0000 +#define FDP_TX_LANE_COUNT_SET 0x0004 +#define FDP_TX_ENHANCED_FRAME_EN 0x0008 +#define FDP_TX_TRAINING_PATTERN_SET 0x000c + +#define FDP_TX_LINK_QUAL_PATTERN_SET 0x0010 +#define FDP_TX_SCRAMBLING_DISABLE 0x0014 +#define FDP_TX_DOWNSPREAD_CTRL 0x0018 +#define FDP_TX_ALT_SCRAMBLER_RESET 0x001c +#define FDP_TX_HBR2_SCRAMBLER_RESET 0x0020 +#define FDP_TX_DISPLAYPORT_VERSION 0x0024 +#define FDP_TX_LANE_REMAP 0x002C + +#define FDP_TX_ENABLE 0x0080 +#define FDP_TX_ENABLE_MAIN_STREAM 0x0084 +#define FDP_TX_ENABLE_SEC_STREAM 0x0088 +#define FDP_TX_SEC_DATA_WINDOW 0x008C +#define FDP_TX_LINK_SOFT_RESET 0x0090 +#define FDP_TR_INPUT_COURCE_ENABLE 0x0094 + +#define FDP_TX_FORCE_SCRAMBLER_RESET 0x00C0 +#define FDP_TX_SOURCE_CONTROL_STATUS 0x00C4 +#define FDP_TX_DATA_CONTROL 0x00C8 + +#define FDP_TX_CORE_CAPABILITY 0x00F8 +#define FDP_TX_CORE_ID 0x00FC + +#define FDP_TX_CMD_REG 0x0100 +#define FDP_TX_FIFO 0x0104 +#define FDP_TX_ADDRESS_REG 0x0108 +#define FDP_TX_CLK_DIVIDER 0x010C +#define FDP_TX_AUX_REPLY_TIMEOUT_INTERVAL 0x0110 +#define FDP_TX_SINK_HPD_STATE 0x0128 +#define FDP_TX_STATUS 0x0130 +#define FDP_TX_RCV_FIFO 0x0134 +#define FDP_TX_RCV_REPLY_REG 0x0138 +#define FDP_TX_RCV_REPLY_COUNT 0x013C + +#define FDP_TX_INTERRUPT 0x0140 +#define FDP_TX_INTERRUPT_MASK 0x0144 +#define FDP_TX_RCV_DATA_COUNT 0x0148 +#define FDP_TX_AUX_TRANSACTION_STATUS 0x014C +#define FDP_TX_TIMER 0x0158 + +/* + Main Link registers +*/ +#define FDPTX_MAIN_LINK_HTOTAL 0x0180 +#define FDPTX_MAIN_LINK_VTOTAL 0x0184 +#define FDPTX_MAIN_LINK_POLARITY 0x0188 +#define FDPTX_MAIN_LINK_HSWIDTH 0x018C +#define FDPTX_MAIN_LINK_VSWIDTH 0x0190 +#define FDPTX_MAIN_LINK_HRES 0x0194 +#define FDPTX_MAIN_LINK_VRES 0x0198 +#define FDPTX_MAIN_LINK_HSTART 0x019C +#define FDPTX_MAIN_LINK_VSTART 0x01A0 +#define FDPTX_MAIN_LINK_MISC0 0x01A4 +#define FDPTX_MAIN_LINK_MISC1 0x01A8 +#define FDPTX_M_VID 0x01AC +#define FDPTX_TRANSFER_UNIT_SIZE 0x01B0 +#define FDPTX_N_VID 0x01B4 +#define FDPTX_USER_PIXEL_WIDTH 0x01B8 +#define FDPTX_DATA_PER_LANE 0x01BC +#define FDPTX_INTERLACED 0x01C0 +#define FDPTX_USER_POLARITY 0x01C4 +#define FDPTX_USER_CONTROL 0x01C8 + +#define FDP_TX_AUX_ERROR_MASK BIT(6) //AUX reply error +#define FDP_TX_GP_TIME_MASK BIT(4) // 通用定时器中断 +#define FDP_TX_AUX_TIMEOUT_MASK BIT(3) //因等待 AUX reply 超时发起中断 +#define FDP_TX_AUX_RECEIVED_MASK BIT(2) //接收到 AUX reply 发起中断 +#define FDP_TX_HPD_INTR_MASK BIT(1) //hpd irq 中断 +#define FDP_TX_HPD_EVENT_MASK BIT(0)//HPD 连接或断开事件 中断 + +#define FDP_TX_STATUS_AUX_ERROR BIT(6) +#define FDP_TX_STATUS_GP_TIME BIT(4) +#define FDP_TX_STATUS_AUX_TIMEOUT BIT(3) +#define FDP_TX_STATUS_AUX_RECEIVED BIT(2) +#define FDP_TX_STATUS_HPD_INTR BIT(1) +#define FDP_TX_STATUS_HPD_EVENT BIT(0) + +/* + eDP CRC registers +*/ +#define FDPTX_EDP_CRC_ENABLE 0x01D0 +#define FDPTX_EDP_CRC_RED 0x01D4 +#define FDPTX_EDP_CRC_GREEN 0x01D8 +#define FDPTX_EDP_CRC_BLUE 0x01DC + +/* write the data to the channel of dp */ +void FDpChannelRegWrite(uintptr addr, uintptr offset, u32 data); + +/* read the data from the channel of dp */ +FError FDpChannelRegRead(uintptr addr, uintptr offset); + +/* write FdpPhy control register */ +void FDpPhyRegWrite(uintptr addr,uintptr offset, u32 data); + +/* read FdpPhy control register */ +FError FDpPhyRegRead(uintptr addr, uintptr offset); + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_phy.h b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_phy.h new file mode 100644 index 0000000000..c8316b8942 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/media/fdcdp_lib/inc/fdp_phy.h @@ -0,0 +1,349 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fdp_phy.h + * Date: 2022-09-08 14:53:42 + * LastEditTime: 2022-09-08 14:53:42 + * Description:  This file is for providing the dp phy register and function + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 Wangzq 2022/12/20 Modify the format and establish the version + */ +#ifndef FDP_PHY_H +#define FDP_PHY_H + +#include "fdp.h" +/* +** DPCD Address +*/ +#define DPCD_REV 0x00000 +#define MAX_LINK_RATE 0x00001 +#define MAX_LANE_COUNT 0x00002 +#define MAX_DOWNSPREAD 0x00003 +#define NORP_DP_PWR_VOLTAGE_CAP 0x00004 +#define DOWN_STRAM_PORT_PRESENT 0x00005 +#define MAIN_LINK_CHANNEL_CODING 0x00006 +#define DOWN_STREAM_PORT_COUNT 0x00007 +#define RECEIVE_PORT0_CAP_0 0x00008 +#define RECEIVE_PORT0_CAP_1 0x00009 +#define RECEIVE_PORT1_CAP_0 0x0000A +#define RECEIVE_PORT1_CAP_1 0x0000B +#define I2C_SPEED_CONTROL_CAPABILITIES 0x0000C +#define EDP_CONFIGURATION_CAP 0x0000D +#define TRAINING_AUX_RD_INTERVAL 0x0000E +#define ADAPTOR_CAP 0x0000F + +#define MSTM_CAP 0x00021 +#define NUMBER_OF_AUDIO_ENDPOINTS 0x00022 +#define AV_SYNC_DATA_BLOCK_DEC 0x00023 +#define AV_SYNC_DATA_BLOCK_DEC_LOW 0x00024 +#define AV_SYNC_DATA_BLOCK_DEC_HIGH 0x00025 +#define AV_SYNC_DATA_BLOCK_PP_LOW 0x00026 +#define AV_SYNC_DATA_BLOCK_PP_HIGH 0x00027 +#define AV_SYNC_DATA_BLOCK_INTER 0x00028 +#define AV_SYNC_DATA_BLOCK_PROG 0x00029 +#define AV_SYNC_DATA_BLOCK_REP_LOW 0x0002A +#define AV_SYNC_DATA_BLOCK_DEL_LOW 0x0002B +#define AV_SYNC_DATA_BLOCK_DEL_MID 0x0002C +#define AV_SYNC_DATA_BLOCK_DEL_HIGH 0x0002D + +#define RX_GTC_VALUE_0 0x00054 +#define RX_GTC_VALUE_1 0x00055 +#define RX_GTC_VALUE_2 0X00056 +#define RX_GTC_VALUE_3 0X00057 +#define RX_GTC_MSTR_REQ 0x00058 +#define RX_GTC_FREQ_LOCK_DONE 0x00059 +#define RX_GTC_PHASE_SKEW_OFFSET_0 0x0005A +#define RX_GTC_PHASE_SKEW_OFFSET_1 0x0005B +#define DSC_SUPPORT 0x00060 +#define DSC_ALGORITHM_REVISION 0x00061 +#define DSC_RC_BUFFER_CLOCK_SIZE 0x00062 +#define DSC_RC_BUFFER_SIZE 0x00063 +#define DSC_SLICE_BAPABILITIES_1 0x00064 +#define DSC_LINE_BUFFER_BLT_DEPTH 0x00065 +#define DSC_BLOCK_PREDICTION_SUPPORT 0x00066 +#define MAX_BITS_PER_PIXEL_SUPPORTED 0x00067 +#define DSC_COLOR_FORMAT_CAPABILITIES 0x00069 +#define DSC_COLOR_DEPTH_CAPABILITIES 0x0006A +#define PEAK_DSC_THROUGHPUT 0x0006B +#define DSC_MAX_SLICE_WIDTH 0x0006C +#define DSC_SLICE_CAPABILITIES_2 0x0006D +#define MIN_BITS_PER_PIXEL_SUPPORTED 0x0006E + +#define PANELSELFREF_CAPSUP_REV 0x00070 +#define PANEL_SELF_REFRESH_CAPABILITIES 0x00071 +#define DETAILED_CAPABILITIES_INFO 0x00080 /*80-8F \ + */ +#define FEC_CAPABILITY 0x00090 + +#define LINK_BW_SET 0x00100 +#define LANE_COUNT_SET 0x00101 +#define TRAINING_PATTERN_SET 0x00102 +#define TRAINING_LANE0_SET 0x00103 +#define TRAINING_LANE1_SET 0x00104 +#define TRAINING_LANE2_SET 0x00105 +#define TRAINING_LANE3_SET 0x00106 +#define DOWNSPREAD_CTRL 0x00107 +#define MAIN_LINK_CHANNEL_CODING_SET 0x00108 +#define I2C_SPEED_CONTROL_STATUS 0x00109 +#define EDP_CONFIGURATION_SET 0x0010A +#define LINK_QUAL_LANE0_SET 0x0010B +#define LINK_QUAL_LANE1_SET 0x0010C +#define LINK_QUAL_LANE2_SET 0x0010D +#define LINK_QUAL_LANE3_SET 0x0010E +#define MSTM_CTRL 0x00111 +#define AUDIO_DELAY_7_0 0x00112 +#define AUDIO_DELAY_15_8 0x00113 +#define AUDIO_DELAY_23_16 0x00114 +#define LINK_RATE_SET_TX_GTC_CAPABILITY 0x00115 +#define UPSTREAM_DEVICE_DP_PWR_NEED 0x00118 +#define EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_GRANT 0x00119 +#define FEC_CONFIGURATION 0x00120 +#define TX_GTC_VALUE_7_0 0x00154 +#define TX_GTC_VALUE_15_8 0x00155 +#define TX_GTC_VALUE_23_16 0x00156 +#define TX_GTC_VALUE_31_24 0x00157 +#define RX_GTC_VALUE_PHASE_SKEW_EN 0x00158 +#define TX_GTC_FREQ_LOCK_DONE 0x00159 +#define TX_GTC_PHASE_CKEW_OFFERT_7_0 0x0015A +#define TX_GTC_PHASE_CKEW_OFFERT_15_8 0x0015B +#define DSC_ENABLE 0x00160 +#define ADAPTOR_CTRL 0x001A0 +#define BRANCH_DEVICE_CTRL 0x001A1 +#define PAYLOAD_ALLOCATE_SET 0x001C0 +#define PAYLOAD_ALLOCATE_START_TIME_SLOT 0x001C1 +#define PAYLOAD_ALLOCATE_TIME_SLOT_COUNT 0x001C2 + +#define SINK_COUNT 0x00200 +#define DEVICE_SERVICE_IRQ_VECTOR 0x00201 +#define LANE0_1_STATUS 0x00202 +#define LANE2_3_STATUS 0x00203 +#define LANE_ALIGN_STATUS_UPDATED 0x00204 +#define SINK_STATUS 0x00205 +#define ADJUST_REQUEST_LANE0_1 0x00206 +#define ADJUST_REQUEST_LANE2_3 0x00207 +#define TRAINING_SCORE_LANE0 0x00208 +#define TRAINING_SCORE_LANE1 0x00209 +#define TRAINING_SCORE_LANE2 0x0020A +#define TRAINING_SCORE_LANE3 0x0020B +#define SYMBOL_ERROR_COUNT_LANE0_LOW 0x00210 +#define SYMBOL_ERROR_COUNT_LANE0_HIGH 0x00211 +#define SYMBOL_ERROR_COUNT_LANE1_LOW 0x00212 +#define SYMBOL_ERROR_COUNT_LANE1_HIGH 0x00213 +#define SYMBOL_ERROR_COUNT_LANE2_LOW 0x00214 +#define SYMBOL_ERROR_COUNT_LANE2_HIGH 0x00215 +#define SYMBOL_ERROR_COUNT_LANE3_LOW 0x00216 +#define SYMBOL_ERROR_COUNT_LANE3_HIGH 0x00217 +#define TEST_REQUEST 0x00208 +#define TEST_LINK_RATE 0x00219 +#define TEST_LANE_COUNT 0x00220 +#define TEST_PATTERN 0x00221 +#define TEST_H_TOTAL_HIGH 0x00222 +#define TEST_H_TOTAL_LOW 0x00223 +#define TEST_V_TOTAL_HIGH 0x00224 +#define TEST_V_TOTAL_LOW 0x00225 +#define TEST_H_START_HIGH 0x00226 +#define TEST_H_START_LOW 0x00227 +#define TEST_V_START_HIGH 0x00228 +#define TEST_V_START_LOW 0x00229 +#define TEST_HSYNC_HIGH 0x0022A +#define TEST_HSYNC_LOW 0x0022B +#define TEST_VSYNC_HIGH 0x0022C +#define TEST_VSYNC_LOW 0x0022D +#define TEST_H_WIDTH_HIGH 0x0022E +#define TEST_H_WIDTH_LOW 0x0022F +#define TEST_V_HEIGHT_HIGH 0x00230 +#define TEST_V_HEIGHT_LOW 0x00231 +#define TEST_MISC_LOW 0x00232 +#define TEST_MISC_HIGH 0x00233 +#define TEST_REFRESH_RATE_NUMERATOR 0x00234 +#define TEST_CRC_R_CR_LOW 0x00240 +#define TEST_CRC_R_CR_HIGH 0x00241 +#define TEST_CRC_G_Y_LOW 0x00242 +#define TEST_CRC_G_Y_HIGH 0x00243 +#define TEST_CRC_B_CB_LOW 0x00244 +#define TEST_CRC_B_CB_HIGH 0x00245 +#define TEST_CRC_COUNT 0x00246 +#define PHY_TEST_PATTERN 0x00248 +#define HBR2_COMPLIANCE_SCRAMBLER_RESET_7_0 0x0024A +#define HBR2_COMPLIANCE_SCRAMBLER_RESET_15_8 0x0024B +#define TEST_80BIT_CUSTOM_PATTERN_7_0 0x00250 +#define TEST_80BIT_CUSTOM_PATTERN_15_8 0x00251 +#define TEST_80BIT_CUSTOM_PATTERN_23_16 0x00252 +#define TEST_80BIT_CUSTOM_PATTERN_31_24 0x00253 +#define TEST_80BIT_CUSTOM_PATTERN_39_32 0x00254 +#define TEST_80BIT_CUSTOM_PATTERN_47_40 0x00255 +#define TEST_80BIT_CUSTOM_PATTERN_55_48 0x00256 +#define TEST_80BIT_CUSTOM_PATTERN_63_56 0x00257 +#define TEST_80BIT_CUSTOM_PATTERN_71_64 0x00258 +#define TEST_80BIT_CUSTOM_PATTERN_79_72 0x00259 +#define CONTINUOUS_80BIT_PATTERN_FROM_DPRX_AUX_CH_CAP 0x0025A +#define CONTINUOUS_80BIT_PATTERN_FROM_DPRX_AUX_CH_CTRL 0x0025B +#define TEST_RESPONSE 0x00260 +#define TEST_EDID_CHECHSUM 0x00261 +#define TEST_SINK 0x00270 +#define TEST_AUDIO_MODE 0x00271 +#define TEST_AUDIO_PATTERN_TYPE 0x00272 +#define TEST_AUDIO_PERIOD_CH_1 0x00273 +#define TEST_AUDIO_PERIOD_CH_2 0x00274 +#define TEST_AUDIO_PERIOD_CH_3 0x00275 +#define TEST_AUDIO_PERIOD_CH_4 0x00276 +#define TEST_AUDIO_PERIOD_CH_5 0x00277 +#define TEST_AUDIO_PERIOD_CH_6 0x00278 +#define TEST_AUDIO_PERIOD_CH_7 0x00279 +#define TEST_AUDIO_PERIOD_CH_8 0x0027A +#define FEC_STATUS 0x00280 +#define FEC_ERROR_COUNT0 0x00281 +#define FEC_ERROR_COUNT1 0x00282 +#define PAYLOAD_TABLE_UPDATE_STATUS 0x002C0 + +#define IEEE_OUI 0x00300 +#define DEVICE_ID_STRING 0x00303 +#define HARDWARE_REVISION 0x00309 +#define FIRMWARE_SOFTWARE_MAJOR_REV 0x0030A +#define FIRMWARE_SOFTWARE_MINOR_REV 0x0030B + +#define SET_POWER_SET_DP_PWR_VALTAGE 0x00600 + +#define SINK_COUNT_ESI 0x02002 +#define DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x02003 +#define DEVICE_SERVICE_IRQ_VECTOR_ESI1 0x02004 +#define LINK_SERVICE_IRQ_VECTOR_ESI0 0x02005 +#define LANE0_1_STATUS_ESI 0x0200C +#define LANE2_3_STATUS_ESI 0x0200D +#define LANE_ALIGN_STATUS_UPDATED_ESI 0x0200E +#define SINK_STATUS_ESI 0x0200F + +#define LINK_TRAINING_TPS1 0x01 +#define LINK_TRAINING_TPS2 0x02 +#define LINK_TRAINING_TPS3 0x03 +#define LINK_TRAINING_TPS4 0x07 + +/* + DP PHY Register +*/ +#define REG_32BIT_SEL 0x40000 +#define REG_EB_MODE 0x40004 +#define REG_RX_EQ_TRAINING 0x40008 +#define REG_RX_TERMINATION 0x4000c +#define REG_128B_ENC_BYP 0x40010 +#define REG_TX_ONE_ZEROS 0x40014 +#define REG_TX_PATTTERN 0x40018 +#define REG_RXSTARTHIGH 0x4001c +#define REG_LINKEVAL_MERIT 0x40020 +#define REG_MODE 0x40034 +#define REG_L1_SS_SEL 0x40038 +#define REG_RX_ELEC_IDLE_DET_EN 0x4003c +#define REG_TX_CMN_MODE_EN 0x40040 +#define REG_FULLRT_DIV 0x40048 +#define REG_MISC 0x4004c +#define REG_XCVR_POWER_STATE_REQ 0x402bc /* 0x40210*/ +#define REG_PLLCLK_EN 0x40214 +#define REG_PMA_STANDARD_MODE 0x40218 +#define REG_PMA_DATA_WIDTH 0x4021c +#define REG_TX_ELEC_IDLE 0x40220 +#define REG_TX_DEEMPH_0 0x40224 +#define REG_GET_LOCAL_PRESET 0x40228 +#define REG_LOCAL_PRESET_INDEX 0x4022c +#define REG_PMA_VMARGIN 0x40230 +#define REG_PMA_LOW_POWER_SWING 0x40234 +#define REG_PMA_RX_EQ_TRAINING_DATA_VALID 0x40238 +#define REG_PMA_RX_EQ_EVAL 0x4023c +#define REG_MAC_SRC_SEL 0x40240 +#define REG_DIV_SEL0 0x40244 +#define REG_PMA_TX_RCV_DETECT 0x40248 +#define REG_PHY_MODE 0x4024c +#define REG_APB_RESET_DEASSERT 0x40250 +#define REG_PHY_RESET_DEASSERT 0x40254 +#define REG_PHY_RESET_LINK_DEASSERT 0x40258 +#define REG_PHY_INTERRUPT 0x4025c +#define REG_SGMII_DPSEL_INIT 0x40260 + +#define PHY_PLL_CFG 0x30038 +#define CMN_PDIAG_PLL0_CLK_SEL_M0 0x684 +#define XCVR_DIAG_HSCLK_SEL 0x10398 +#define XCVR_DIAG_HSCLK_DIV 0x1039c +#define XCVR_DIAG_PLLDRC_CTRL 0x10394 +#define CMN_PLL0_DSM_DIAG_M0 0x250 +#define CMN_PLL0_VCOCAL_REFTIM_START 0x218 +#define CMN_PLL0_VCOCAL_TCTRL 0x208 +#define CMN_PDIAG_PLL0_CP_PADJ_M0 0x690 +#define CMN_PDIAG_PLL0_CP_IADJ_M0 0x694 +#define CMN_PDIAG_PLL0_FILT_PADJ_M0 0x698 +#define CMN_PLL0_INTDIV_M0 0x240 +#define CMN_PLL0_FRACDIVL_M0 0x244 +#define CMN_PLL0_FRACDIVH_M0 0x248 +#define CMN_PLL0_HIGH_THR_M0 0x24c +#define CMN_PDIAG_PLL0_CTRL_M0 0x680 +#define CMN_PLL0_VCOCAL_PLLCNT_START 0x220 +#define CMN_PLL0_LOCK_REFCNT_START 0x270 +#define CMN_PLL0_LOCK_PLLCNT_START 0x278 +#define CMN_PLL0_LOCK_PLLCNT_THR 0x27c +#define TX_PSC_A0 0x10400 +#define TX_PSC_A2 0x10408 +#define TX_PSC_A3 0x1040c +#define RX_PSC_A0 0x20000 +#define RX_PSC_A2 0x20008 +#define RX_PSC_A3 0x2000c +#define RX_PSC_CAL 0x20018 +#define XCVR_DIAG_BIDI_CTRL 0x103a8 +#define RX_REE_GCSM1_CTRL 0x20420 +#define RX_REE_GCSM2_CTRL 0x20440 +#define RX_REE_PERGCSM_CTRL 0x20460 +#define TX_DIAG_ACYA 0x1079c +#define TX_TXCC_CTRL 0x10100 +#define DRV_DIAG_TX_DRV 0x10318 +#define TX_TXCC_MGNFS_MULT_000 0x10140 +#define TX_TXCC_CPOST_MULT_00 0x10130 +#define PHY_PMA_CMN_CTRL2 0x38004 +#define PHY_PMA_PLL_RAW_CTRL 0x3800c + +FError FDptxPhyGetLaneCount(FDpCtrl *instance_p, u8 *lanecount); + +FError FDpTxPhyGetLinkRate(FDpCtrl *instance_p, u32 *linkrate); + +/* DP phy date rate change.*/ +void FDpLinkPhyChangeRate(FDpCtrl *instance_p, u32 link_rate); + +/* Get sink ENHANCED_FRAME_CAP */ +FError FDpTxPhyGetEnhancedFrameCap(FDpCtrl *instance_p); + +/* configure the PHY for the specified link rate */ +FError FDpTxPhyUpdateLinkRate(FDpCtrl *instance_p, u32 link_rate); + +/* set the lane count in the PHY */ +void FDpTxPhySetLaneCount(FDpCtrl *instance_p, u32 lane_count); + +/*Get voltage swing of a specified lane.Voltage swing has three levels*/ +FError FDpTxSourceVswingForValue(FDpCtrl *instance_p, u8 lane_num); + +/* Get pre-emphasis level of a specified lane*/ +FError FDpTxSourcePreemphasisForValue(FDpCtrl *instance_p, u8 lane_num); + +/* Get sink TPS4 support.*/ +FError FDpTxPhyTps4Supported(FDpCtrl *instance_p); + +/* Get sink TPS3 support.*/ +FError FDpTxPhyTps3Supported(FDpCtrl *instance_p); + +/* Get Swing and pre-emphasis level form sink*/ +FError FDpTxPhyGetAdjustRequest(FDpCtrl *instance_p, u8 *swing, u8 *pre_emphasis); + +/*Display phy initialization */ +void FDpLinkPhyInit(FDpCtrl *instance_p, u32 link_rate); + +/* Voltage swing and pre-emphasis training.*/ +void FDpLinkPhyChangeVsWing(FDpCtrl *instance_p, u32 vswing, u32 pre_emphasis); +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/mio/Kconfig b/bsp/phytium/libraries/standalone/drivers/mio/Kconfig index 018035d6e8..f92d3360c1 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/mio/Kconfig @@ -2,7 +2,7 @@ menu "Hardware Mio Configuration" config ENABLE_MIO bool prompt "Use Mio" - depends on TARGET_E2000S || TARGET_E2000D || TARGET_E2000Q + depends on TARGET_E2000 || TARGET_TARDIGRADE default n endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.c b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.c index ab35e436aa..7c24c102ed 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.c +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.c @@ -1,25 +1,27 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fmio.c * Date: 2022-07-06 15:01:30 * LastEditTime: 2022-07-06 15:01:30 - * Description:  This file is for + * Description:  This file is for user external interface * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/07/06 first commit */ + #include #include "fmio_hw.h" #include "fmio.h" @@ -27,6 +29,7 @@ /***************** Macros (Inline Functions) Definitions *********************/ #define FMIO_DEBUG_TAG "MIO" #define FMIO_ERROR(format, ...) FT_DEBUG_PRINT_E(FMIO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FMIO_WARN(format, ...) FT_DEBUG_PRINT_W(FMIO_DEBUG_TAG, format, ##__VA_ARGS__) #define FMIO_INFO(format, ...) FT_DEBUG_PRINT_I(FMIO_DEBUG_TAG, format, ##__VA_ARGS__) #define FMIO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FMIO_DEBUG_TAG, format, ##__VA_ARGS__) @@ -41,26 +44,25 @@ FError FMioFuncInit(FMioCtrl *instance_p, u32 mio_type) { FASSERT(instance_p); - FError ret = FMIO_SUCCESS; + FError ret = FMIO_SUCCESS; - /* - * If the device is started, disallow the initialize and return a Status - * indicating it is started. This allows the user to de-initialize the device - * and reinitialize, but prevents a user from inadvertently - * initializing. - */ - if (FT_COMPONENT_IS_READY == instance_p->is_ready) - { - FMIO_ERROR("device is already initialized!!!"); - return FMIO_ERR_INVAL_STATE; - } + /* + * If the device is started, disallow the initialize and return a Status + * indicating it is started. This allows the user to de-initialize the device + * and reinitialize, but prevents a user from inadvertently + * initializing. + */ + if (FT_COMPONENT_IS_READY == instance_p->is_ready) + { + FMIO_WARN("Device is already initialized."); + } - ret = FMioSelectFunc(instance_p->config.mio_base_addr, mio_type); - if (FMIO_SUCCESS == ret) - { - instance_p->is_ready = FT_COMPONENT_IS_READY; - } - return ret; + ret = FMioSelectFunc(instance_p->config.mio_base_addr,mio_type); + if (FMIO_SUCCESS == ret) + { + instance_p->is_ready = FT_COMPONENT_IS_READY; + } + return ret; } /** @@ -72,16 +74,16 @@ FError FMioFuncInit(FMioCtrl *instance_p, u32 mio_type) FError FMioFuncDeinit(FMioCtrl *instance_p) { FASSERT(instance_p); - FError ret = FMIO_SUCCESS; + FError ret = FMIO_SUCCESS; - instance_p->is_ready = 0; + instance_p->is_ready = 0; - /* 重新配置成默认IIC模式 */ - ret = FMioSelectFunc(instance_p->config.mio_base_addr, FMIO_FUNC_SET_I2C); + /* 重新配置成默认IIC模式 */ + ret = FMioSelectFunc(instance_p->config.mio_base_addr, FMIO_FUNC_SET_I2C); - memset(instance_p, 0, sizeof(*instance_p)); + memset(instance_p, 0, sizeof(*instance_p)); - return ret; + return ret; } /** @@ -90,24 +92,24 @@ FError FMioFuncDeinit(FMioCtrl *instance_p) * @return {uintptr} * @param {FMioCtrl} *instance_p */ -uintptr FMioFuncGetAddress(FMioCtrl *instance_p, u32 mio_type) +uintptr FMioFuncGetAddress(FMioCtrl *instance_p,u32 mio_type) { - FASSERT(instance_p); - FError ret = FMIO_SUCCESS; - - if (instance_p->is_ready != FT_COMPONENT_IS_READY) - { - FMIO_ERROR("Mio instance_id: %d ,not init.", instance_p->config.instance_id); - return FMIO_ERR_NOT_READY; - } + FASSERT(instance_p); + FError ret = FMIO_SUCCESS; + + if (instance_p->is_ready != FT_COMPONENT_IS_READY) + { + FMIO_ERROR("Mio instance_id: %d ,not init.",instance_p->config.instance_id ); + return FMIO_ERR_NOT_READY; + } if (FMioGetFunc(instance_p->config.mio_base_addr) != mio_type) { - FMIO_ERROR("Mio instance_id: %d ,mio_type error,please init type first.", instance_p->config.instance_id); + FMIO_ERROR("Mio instance_id: %d ,mio_type error, initialize the type first.", instance_p->config.instance_id); return FMIO_ERR_INVAL_STATE; } - return instance_p->config.func_base_addr; + return instance_p->config.func_base_addr; } /** @@ -116,22 +118,22 @@ uintptr FMioFuncGetAddress(FMioCtrl *instance_p, u32 mio_type) * @return {u32}中断号 * @param {FMioCtrl} *instance_p */ -u32 FMioFuncGetIrqNum(FMioCtrl *instance_p, u32 mio_type) +u32 FMioFuncGetIrqNum(FMioCtrl *instance_p,u32 mio_type) { - FASSERT(instance_p); - FError ret = FMIO_SUCCESS; - - if (instance_p->is_ready != FT_COMPONENT_IS_READY) - { - FMIO_ERROR("Mio instance_id: %d ,not init.", instance_p->config.instance_id); - return FMIO_ERR_NOT_READY; - } + FASSERT(instance_p); + FError ret = FMIO_SUCCESS; + + if (instance_p->is_ready != FT_COMPONENT_IS_READY) + { + FMIO_ERROR("Mio instance_id: %d ,not init.",instance_p->config.instance_id); + return FMIO_ERR_NOT_READY; + } if (FMioGetFunc(instance_p->config.mio_base_addr) != mio_type) { - FMIO_ERROR("Mio instance_id: %d ,mio_type error,please init type first.", instance_p->config.instance_id); + FMIO_ERROR("Mio instance_id: %d ,mio_type error, initialize the type first.", instance_p->config.instance_id); return FMIO_ERR_INVAL_STATE; } - return instance_p->config.irq_num; + return instance_p->config.irq_num; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.h b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.h index 5343130add..2064595197 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.h +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio.h @@ -14,15 +14,16 @@ * FilePath: fmio.h * Date: 2022-06-21 15:40:06 * LastEditTime: 2022-06-21 15:40:06 - * Description:  This file is for + * Description:  This file is for user external interface definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/06/21 first commit */ -#ifndef DRIVERS_MIO_FMIO_H -#define DRIVERS_MIO_FMIO_H +#ifndef FMIO_H +#define FMIO_H #ifdef __cplusplus extern "C" @@ -47,9 +48,9 @@ extern "C" typedef struct { - u32 instance_id; /*mio id*/ + u32 instance_id; /*mio id*/ uintptr func_base_addr; /*I2C or UART function address*/ - u32 irq_num; /* Device intrrupt id */ + u32 irq_num; /* Device intrrupt id */ uintptr mio_base_addr; /*MIO control address*/ } FMioConfig; /*mio configs*/ diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_g.c b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_g.c index e018aa6452..09fd293ab6 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_g.c +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_g.c @@ -14,12 +14,12 @@ * FilePath: fmio_g.c * Date: 2022-06-20 21:05:07 * LastEditTime: 2022-06-20 21:05:07 - * Description:  This file is for mio + * Description:  This file is for mio static configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 0.1.0 liu 2022.06.20 init + * 1.0 liushengming 2022/06/20 first commit */ /***************************** Include Files *********************************/ @@ -29,102 +29,104 @@ /************************** Constant Definitions *****************************/ -const FMioConfig FMioConfigTbl[MIO_INSTANCE_NUM] = +const FMioConfig FMioConfigTbl[FMIO_NUM] = { { - .instance_id = MIO_INSTANCE_0, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_0), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_0), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_0) + .instance_id = FMIO0_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO0_ID), + .irq_num = FMIO_IRQ_NUM(FMIO0_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO0_ID) }, { - .instance_id = MIO_INSTANCE_1, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_1), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_1), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_1) + .instance_id = FMIO1_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO1_ID), + .irq_num = FMIO_IRQ_NUM(FMIO1_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO1_ID) }, { - .instance_id = MIO_INSTANCE_2, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_2), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_2), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_2) + .instance_id = FMIO2_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO2_ID), + .irq_num = FMIO_IRQ_NUM(FMIO2_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO2_ID) }, { - .instance_id = MIO_INSTANCE_3, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_3), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_3), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_3) + .instance_id = FMIO3_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO3_ID), + .irq_num = FMIO_IRQ_NUM(FMIO3_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO3_ID) }, { - .instance_id = MIO_INSTANCE_4, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_4), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_4), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_4) + .instance_id = FMIO4_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO4_ID), + .irq_num = FMIO_IRQ_NUM(FMIO4_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO4_ID) }, { - .instance_id = MIO_INSTANCE_5, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_5), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_5), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_5) + .instance_id = FMIO5_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO5_ID), + .irq_num = FMIO_IRQ_NUM(FMIO5_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO5_ID) }, { - .instance_id = MIO_INSTANCE_6, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_6), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_6), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_6) + .instance_id = FMIO6_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO6_ID), + .irq_num = FMIO_IRQ_NUM(FMIO6_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO6_ID) }, { - .instance_id = MIO_INSTANCE_7, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_7), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_7), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_7) + .instance_id = FMIO7_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO7_ID), + .irq_num = FMIO_IRQ_NUM(FMIO7_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO7_ID) + }, +#if defined(CONFIG_TARGET_E2000) + { + .instance_id = FMIO8_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO8_ID), + .irq_num = FMIO_IRQ_NUM(FMIO8_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO8_ID) }, { - .instance_id = MIO_INSTANCE_8, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_8), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_8), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_8) + .instance_id = FMIO9_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO9_ID), + .irq_num = FMIO_IRQ_NUM(FMIO9_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO9_ID) }, { - .instance_id = MIO_INSTANCE_9, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_9), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_9), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_9) + .instance_id = FMIO10_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO10_ID), + .irq_num = FMIO_IRQ_NUM(FMIO10_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO10_ID) }, { - .instance_id = MIO_INSTANCE_10, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_10), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_10), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_10) + .instance_id = FMIO11_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO11_ID), + .irq_num = FMIO_IRQ_NUM(FMIO11_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO11_ID) }, { - .instance_id = MIO_INSTANCE_11, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_11), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_11), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_11) + .instance_id = FMIO12_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO12_ID), + .irq_num = FMIO_IRQ_NUM(FMIO12_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO12_ID) }, { - .instance_id = MIO_INSTANCE_12, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_12), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_12), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_12) + .instance_id = FMIO13_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO13_ID), + .irq_num = FMIO_IRQ_NUM(FMIO13_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO13_ID) }, { - .instance_id = MIO_INSTANCE_13, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_13), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_13), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_13) + .instance_id = FMIO14_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO14_ID), + .irq_num = FMIO_IRQ_NUM(FMIO14_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO14_ID) }, { - .instance_id = MIO_INSTANCE_14, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_14), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_14), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_14) - }, - { - .instance_id = MIO_INSTANCE_15, - .func_base_addr = FMIO_BASE_ADDR(MIO_INSTANCE_15), - .irq_num = FMIO_IRQ_NUM(MIO_INSTANCE_15), - .mio_base_addr = FMIO_BASE_SET_ADDR(MIO_INSTANCE_15) + .instance_id = FMIO15_ID, + .func_base_addr = FMIO_BASE_ADDR(FMIO15_ID), + .irq_num = FMIO_IRQ_NUM(FMIO15_ID), + .mio_base_addr = FMIO_BASE_SET_ADDR(FMIO15_ID) } +#endif }; diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.c b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.c index 336d93c52e..c0773f88f1 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.c @@ -14,12 +14,12 @@ * FilePath: fmio_hw.c * Date: 2022-06-20 21:05:23 * LastEditTime: 2022-06-20 21:05:23 - * Description:  This file is for mio + * Description:  This file is for mio hardware operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 0.1.0 liushengming 2022.06.20 init + * 1.0 liushengming 2022/06/20 first commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.h b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.h index acc1699fae..35120d0445 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_hw.h @@ -14,20 +14,15 @@ * FilePath: fmio_hw.h * Date: 2022-06-20 21:05:34 * LastEditTime: 2022-06-20 21:05:34 - * Description:  This file is for mio + * Description:  This file is for mio hardware define * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 0.1.0 liushengming 2022.06.20 init + * 1.0 liushengming 2022/06/20 init */ -#ifndef DRIVERS_MIO_FMIO_HW_H -#define DRIVERS_MIO_FMIO_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FMIO_HW_H +#define FMIO_HW_H #include "fparameters.h" #include "fio.h" @@ -35,6 +30,11 @@ extern "C" #include "fdebug.h" #include "ferror_code.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ @@ -56,7 +56,9 @@ enum { FMIO_FUNC_SET_I2C = 0b00, FMIO_FUNC_SET_UART = 0b01, - +#if defined(TARDIGRADE) + FMIO_FUNC_SET_PWM = 0b10, +#endif FMIO_NUM_OF_MIO_FUNC }; diff --git a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_sinit.c b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_sinit.c index a971924e37..e1dbac3c6f 100644 --- a/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/mio/fmio/fmio_sinit.c @@ -14,12 +14,12 @@ * FilePath: fmio_sinit.c * Date: 2022-06-20 20:33:25 * LastEditTime: 2022-06-20 20:33:25 - * Description:  This file is for mio + * Description:  This file is for mio static initialization functionality * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 0.1.0 liushengming 2022.06.20 init + * 1.0 liushengming 2022/06/20 first commit */ #include "ftypes.h" #include "fparameters.h" @@ -28,7 +28,7 @@ #include "fmio_hw.h" -extern FMioConfig FMioConfigTbl[MIO_INSTANCE_NUM]; +extern FMioConfig FMioConfigTbl[FMIO_NUM]; /***************** Macros (Inline Functions) Definitions *********************/ #define FMIO_DEBUG_TAG "MIO" @@ -44,11 +44,11 @@ extern FMioConfig FMioConfigTbl[MIO_INSTANCE_NUM]; */ const FMioConfig *FMioLookupConfig(u32 instance_id) { - FASSERT(instance_id < MIO_INSTANCE_NUM); + FASSERT(instance_id < FMIO_NUM); const FMioConfig *pconfig = NULL; u32 index; - for (index = 0; index < (u32)MIO_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FMIO_NUM; index++) { if (FMioConfigTbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/Kconfig b/bsp/phytium/libraries/standalone/drivers/mmc/Kconfig index 31805318a8..4a7b0bf8b9 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/mmc/Kconfig @@ -3,7 +3,6 @@ config ENABLE_FSDMMC prompt "Use FSdmmc" default n depends on USE_SDMMC - depends on TARGET_F2000_4 || TARGET_D2000 help Select FSdmmc driver component @@ -12,8 +11,7 @@ config ENABLE_FSDIO prompt "Use FSdio" default n depends on USE_SDMMC - depends on TARGET_E2000S || TARGET_E2000D || TARGET_E2000Q help Select FSdio driver component - - + + \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.c index 771e4ff9ca..51e20c0a5c 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.c @@ -14,7 +14,7 @@ * FilePath: fsdio.c * Date: 2022-05-26 16:27:54 * LastEditTime: 2022-05-26 16:27:54 - * Description:  This files is for SDIO user function implementation + * Description:  This file is for SDIO user function implementation * * Modify History: * Ver   Who        Date         Changes @@ -67,18 +67,20 @@ FError FSdioCfgInitialize(FSdio *const instance_p, const FSdioConfig *input_conf if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FSDIO_WARN("device is already initialized!!!"); + FSDIO_WARN("Device is already initialized!!!"); } if (&instance_p->config != input_config_p) + { instance_p->config = *input_config_p; + } ret = FSdioReset(instance_p); /* reset the device */ if (FSDIO_SUCCESS == ret) { instance_p->is_ready = FT_COMPONENT_IS_READY; - FSDIO_INFO("device initialize success !!!"); + FSDIO_INFO("Device initialize success !!!"); } return ret; @@ -125,7 +127,7 @@ FError FSdioSetClkFreq(FSdio *const instance_p, u32 input_clk_hz) u32 first_uhs_div, tmp_ext_reg, div_reg; FError ret = FSDIO_SUCCESS; - FSDIO_INFO("set clk as %ld", input_clk_hz); + FSDIO_INFO("set clk as %ld.", input_clk_hz); /* must set 2nd stage clcok first then set 1st stage clock */ /* experimental uhs setting --> 2nd stage clock, below setting parameters get from @@ -149,18 +151,22 @@ FError FSdioSetClkFreq(FSdio *const instance_p, u32 input_clk_hz) /* update uhs setting */ ret = FSdioUpdateExternalClk(base_addr, tmp_ext_reg); if (FSDIO_SUCCESS != ret) + { return ret; + } FSdioSetClock(base_addr, FALSE); /* disable clock */ /* send private cmd to update clock */ ret = FSdioSendPrivateCmd(base_addr, FSDIO_CMD_UPD_CLK, 0U); if (FSDIO_SUCCESS != ret) + { return ret; + } /* experimental clk divide setting -- 1st stage clock */ first_uhs_div = 1 + FSDIO_UHS_CLK_DIV_GET(tmp_ext_reg); - div = FSDIO_CLK_RATE_HZ / (2 * first_uhs_div * input_clk_hz); + div = FSDIO_CLK_FREQ_HZ / (2 * first_uhs_div * input_clk_hz); if (div > 2) { sample = div / 2 + 1; @@ -179,20 +185,43 @@ FError FSdioSetClkFreq(FSdio *const instance_p, u32 input_clk_hz) FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET), FSDIO_READ_REG(base_addr, FSDIO_CLKDIV_OFFSET)); - FSDIO_INFO("UHS_REG_EXT ext: 0x%x, CLKDIV: 0x%x", - FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET), - FSDIO_READ_REG(base_addr, FSDIO_CLKDIV_OFFSET)); - FSdioSetClock(base_addr, TRUE); /* enable clock */ /* update clock for 1 stage clock */ ret = FSdioSendPrivateCmd(base_addr, FSDIO_CMD_UPD_CLK, 0U); if (FSDIO_SUCCESS != ret) + { return ret; + } + FSDIO_INFO("FSdioSetClkFreq done."); return ret; } +/** + * @name: FSdioGetClkFreq + * @msg: Get the real Card clock freqency + * @return {u32} real clock freqency in Hz + * @param {FSdio} *instance_p, SDIO controller instance + */ +u32 FSdioGetClkFreq(FSdio *const instance_p) +{ + FASSERT(instance_p); + uintptr base_addr = instance_p->config.base_addr; + + u32 uhs_reg_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET); + u32 first_uhs_div = 1 + FSDIO_UHS_CLK_DIV_GET(uhs_reg_val); + + u32 div_reg_val = FSDIO_READ_REG(base_addr, FSDIO_CLKDIV_OFFSET); + u32 div = FSDIO_CLK_DIVDER_GET(div_reg_val); + + FSDIO_INFO("uhs_reg_val = 0x%x, div_reg_val = 0x%x", uhs_reg_val, div_reg_val); + FSDIO_INFO("first_div = %d, second_div = %d", first_uhs_div, div); + u32 real_clk_hz = FSDIO_CLK_FREQ_HZ / (2 * first_uhs_div * div); + + return real_clk_hz; +} + /** * @name: FSdioWaitClkReady * @msg: Wait clock ready after modify clock setting @@ -213,7 +242,7 @@ static FError FSdioWaitClkReady(uintptr base_addr, int retries) if (!(reg_val & FSDIO_CLK_READY) && (retries <= 0)) { - FSDIO_ERROR("wait clk ready timeout !!! status: 0x%x", + FSDIO_ERROR("Wait clk ready timeout !!! status: 0x%x", reg_val); return FSDIO_ERR_TIMEOUT; } @@ -239,7 +268,9 @@ static FError FSdioUpdateExternalClk(uintptr base_addr, u32 uhs_reg_val) { reg_val = FSDIO_READ_REG(base_addr, FSDIO_GPIO_OFFSET); if (--retries <= 0) + { break; + } } while (!(reg_val & FSDIO_CLK_READY)); @@ -263,12 +294,16 @@ FError FSdioResetCtrl(uintptr base_addr, u32 reset_bits) { reg_val = FSDIO_READ_REG(base_addr, FSDIO_CNTRL_OFFSET); if (--retries <= 0) + { break; + } } while (reset_bits & reg_val); if (retries <= 0) + { return FSDIO_ERR_TIMEOUT; + } return FSDIO_SUCCESS; } @@ -290,13 +325,61 @@ FError FSdioResetBusyCard(uintptr base_addr) FSDIO_SET_BIT(base_addr, FSDIO_CNTRL_OFFSET, FSDIO_CNTRL_CONTROLLER_RESET); reg_val = FSDIO_READ_REG(base_addr, FSDIO_STATUS_OFFSET); if (--retries <= 0) + { break; + } } while (reg_val & FSDIO_STATUS_DATA_BUSY); return (retries <= 0) ? FSDIO_ERR_BUSY : FSDIO_SUCCESS; } +/** + * @name: FSdioPollWaitBusyCard + * @msg: poll wait until card not busy + * @return {FError} FSDIO_SUCCESS if exit with card not busy + * @param {FSdio *const} instance_p, instance of controller + */ +FError FSdioPollWaitBusyCard(FSdio *const instance_p) +{ + FASSERT(instance_p); + FASSERT(instance_p->relax_handler); + uintptr base_addr = instance_p->config.base_addr; + u32 reg_val; + FError err = FSDIO_SUCCESS; + int retries = FSDIO_TIMEOUT; + const u32 busy_bits = FSDIO_STATUS_DATA_BUSY | FSDIO_STATUS_DATA_STATE_MC_BUSY; + + reg_val = FSDIO_READ_REG(base_addr, FSDIO_STATUS_OFFSET); + if (reg_val & busy_bits) + { + FSDIO_WARN("Card is busy, waiting ..."); + } + + do + { + reg_val = FSDIO_READ_REG(base_addr, FSDIO_STATUS_OFFSET); + if (--retries <= 0) + { + break; + } + + if (instance_p->relax_handler) + { + instance_p->relax_handler(); /* wait card busy could be time-consuming */ + } + } + while (reg_val & busy_bits); /* wait busy bits empty */ + + if (--retries <= 0) + { + FSDIO_ERROR("Wait card busy timeout !!!"); + err = FSDIO_ERR_TIMEOUT; + } + + return err; +} + /** * @name: FSdioRestartClk * @msg: restart controller clock from error status @@ -315,12 +398,16 @@ FError FSdioRestartClk(uintptr base_addr) { reg_val = FSDIO_READ_REG(base_addr, FSDIO_CMD_OFFSET); if (--retries <= 0) + { break; + } } while (reg_val & FSDIO_CMD_START); if (retries <= 0) + { return FSDIO_ERR_TIMEOUT; + } /* update clock */ FSdioSetClock(base_addr, FALSE); @@ -330,7 +417,9 @@ FError FSdioRestartClk(uintptr base_addr) ret = FSdioUpdateExternalClk(base_addr, uhs); if (FSDIO_SUCCESS != ret) + { return ret; + } FSDIO_WRITE_REG(base_addr, FSDIO_CLKDIV_OFFSET, clk_div); @@ -376,7 +465,7 @@ static FError FSdioReset(FSdio *const instance_p) ret = FSdioUpdateExternalClk(base_addr, reg_val); if (FSDIO_SUCCESS != ret) { - FSDIO_ERROR("update extern clock failed !!!"); + FSDIO_ERROR("Update extern clock failed !!!"); return ret; } @@ -387,15 +476,19 @@ static FError FSdioReset(FSdio *const instance_p) /* set voltage as 3.3v */ if (FSDIO_SD_1_8V_VOLTAGE == instance_p->config.voltage) + { FSdioSetVoltage1_8V(base_addr, TRUE); + } else + { FSdioSetVoltage1_8V(base_addr, FALSE); + } /* reset controller and card */ ret = FSdioResetCtrl(base_addr, FSDIO_CNTRL_FIFO_RESET | FSDIO_CNTRL_DMA_RESET); if (FSDIO_SUCCESS != ret) { - FSDIO_ERROR("reset controller failed !!!"); + FSDIO_ERROR("Reset controller failed !!!"); return ret; } @@ -403,15 +496,19 @@ static FError FSdioReset(FSdio *const instance_p) ret = FSdioSendPrivateCmd(base_addr, FSDIO_CMD_UPD_CLK, 0U); if (FSDIO_SUCCESS != ret) { - FSDIO_ERROR("update clock failed !!!"); + FSDIO_ERROR("Update clock failed !!!"); return ret; } /* reset card for no-removeable media, e.g. eMMC */ if (TRUE == instance_p->config.non_removable) + { FSDIO_SET_BIT(base_addr, FSDIO_CARD_RESET_OFFSET, FSDIO_CARD_RESET_ENABLE); + } else + { FSDIO_CLR_BIT(base_addr, FSDIO_CARD_RESET_OFFSET, FSDIO_CARD_RESET_ENABLE); + } /* clear interrupt status */ FSDIO_WRITE_REG(base_addr, FSDIO_INT_MASK_OFFSET, 0U); @@ -424,7 +521,9 @@ static FError FSdioReset(FSdio *const instance_p) /* enable card detect interrupt */ if (FALSE == instance_p->config.non_removable) + { FSDIO_SET_BIT(base_addr, FSDIO_INT_MASK_OFFSET, FSDIO_INT_CD_BIT); + } /* enable controller and internal DMA */ FSDIO_SET_BIT(base_addr, FSDIO_CNTRL_OFFSET, FSDIO_CNTRL_INT_ENABLE | FSDIO_CNTRL_USE_INTERNAL_DMAC); @@ -437,7 +536,7 @@ static FError FSdioReset(FSdio *const instance_p) FSdioSetDescriptor(base_addr, (uintptr)NULL); /* set decriptor list as NULL */ FSdioResetIDMA(base_addr); - FSDIO_INFO("init hardware done !!!"); + FSDIO_INFO("Init hardware done !!!"); return ret; } @@ -456,27 +555,39 @@ FError FSdioRestart(FSdio *const instance_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return FSDIO_ERR_NOT_INIT; } /* reset controller */ ret = FSdioResetCtrl(base_addr, FSDIO_CNTRL_FIFO_RESET); if (FSDIO_SUCCESS != ret) + { return ret; + } /* reset controller if in busy state */ ret = FSdioResetBusyCard(base_addr); if (FSDIO_SUCCESS != ret) + { return ret; + } /* reset clock */ ret = FSdioRestartClk(base_addr); if (FSDIO_SUCCESS != ret) + { return ret; + } /* reset internal DMA */ FSdioResetIDMA(base_addr); return ret; +} + +void FSdioRegisterRelaxHandler(FSdio *const instance_p, FSdioRelaxHandler relax_handler) +{ + FASSERT(instance_p); + instance_p->relax_handler = relax_handler; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.h b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.h index 6d1f0ba4b9..a2e2fed38f 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.h +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.h @@ -14,7 +14,7 @@ * FilePath: fsdio.h * Date: 2022-05-26 16:20:52 * LastEditTime: 2022-05-26 16:20:53 - * Description:  This files is for sdio user interface definition + * Description:  This file is for sdio user interface definition * * Modify History: * Ver   Who        Date         Changes @@ -22,15 +22,11 @@ * 1.0 zhugengyu 2021/12/2 init * 1.1 zhugengyu 2022/6/6 modify according to tech manual. * 1.2 zhugengyu 2022/7/15 adopt to e2000 + * 1.3 zhugengyu 2022/11/23 fix multi-block rw issues */ -#ifndef DRIVERS_FSDIO_H -#define DRIVERS_FSDIO_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FSDIO_H +#define FSDIO_H /***************************** Include Files *********************************/ @@ -38,19 +34,24 @@ extern "C" #include "ferror_code.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif /************************** Constant Definitions *****************************/ /* SDIO driver error code */ -#define FSDIO_SUCCESS FT_SUCCESS -#define FSDIO_ERR_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 1) -#define FSDIO_ERR_NOT_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 2) -#define FSDIO_ERR_SHORT_BUF FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 3) -#define FSDIO_ERR_NOT_SUPPORT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 4) -#define FSDIO_ERR_INVALID_STATE FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 5) -#define FSDIO_ERR_TRANS_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 6) -#define FSDIO_ERR_CMD_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 7) -#define FSDIO_ERR_NO_CARD FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 8) -#define FSDIO_ERR_BUSY FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 9) +#define FSDIO_SUCCESS FT_SUCCESS +#define FSDIO_ERR_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 1) +#define FSDIO_ERR_NOT_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 2) +#define FSDIO_ERR_SHORT_BUF FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 3) +#define FSDIO_ERR_NOT_SUPPORT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 4) +#define FSDIO_ERR_INVALID_STATE FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 5) +#define FSDIO_ERR_TRANS_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 6) +#define FSDIO_ERR_CMD_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 7) +#define FSDIO_ERR_NO_CARD FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 8) +#define FSDIO_ERR_BUSY FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 9) +#define FSDIO_ERR_DMA_BUF_UNALIGN FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 10) typedef enum { @@ -80,7 +81,6 @@ typedef enum FSDIO_NUM_OF_EVT } FSdioEvtType; /* SDIO event type */ -#define FSDIO_DEFAULT_BLOCK_SZ 512U #define FSDIO_SD_400KHZ 400000U #define FSDIO_SD_25_MHZ 25000000U #define FSDIO_SD_50_MHZ 50000000U @@ -88,7 +88,7 @@ typedef enum typedef struct _FSdio FSdio; typedef void (*FSdioRelaxHandler)(void); -typedef void (*FSdioEvtHandler)(FSdio *const instance_p, void *args); +typedef void (*FSdioEvtHandler)(FSdio *const instance_p, void *args, u32 status, u32 dmac_status); typedef struct { @@ -155,6 +155,7 @@ typedef struct FSdioTransMode trans_mode; /* Trans mode, PIO/DMA */ FSdioVoltageType voltage; /* Card voltage type */ boolean non_removable; /* No removeable media, e.g eMMC */ + boolean filp_resp_byte_order; /* Some SD protocol implmentation may not do byte-order filp */ } FSdioConfig; /* SDIO intance configuration */ typedef struct _FSdio @@ -164,6 +165,8 @@ typedef struct _FSdio FSdioIDmaDescList desc_list; /* DMA descriptor list, valid in DMA trans mode */ FSdioEvtHandler evt_handlers[FSDIO_NUM_OF_EVT]; /* call-backs for interrupt event */ void *evt_args[FSDIO_NUM_OF_EVT]; /* arguments for event call-backs */ + FSdioRelaxHandler relax_handler; + u32 prev_cmd; /* record previous command code */ } FSdio; /* SDIO intance */ /************************** Variable Definitions *****************************/ @@ -186,17 +189,20 @@ FError FSdioSetIDMAList(FSdio *const instance_p, volatile FSdioIDmaDesc *desc, u /* Set the Card clock freqency */ FError FSdioSetClkFreq(FSdio *const instance_p, u32 input_clk_hz); +/* Get the real Card clock freqency */ +u32 FSdioGetClkFreq(FSdio *const instance_p); + /* Start command and data transfer in DMA mode */ FError FSdioDMATransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); /* Wait DMA transfer finished by poll */ -FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax); +FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); /* Start command and data transfer in PIO mode */ FError FSdioPIOTransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); /* Wait PIO transfer finished by poll */ -FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax); +FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); /* Get cmd response and received data after wait poll status or interrupt signal */ FError FSdioGetCmdResponse(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); @@ -216,9 +222,15 @@ FError FSdioRestart(FSdio *const instance_p); /* Register event call-back function as handler for interrupt events */ void FSdioRegisterEvtHandler(FSdio *const instance_p, FSdioEvtType evt, FSdioEvtHandler handler, void *handler_arg); +/* Register sleep call-back function */ +void FSdioRegisterRelaxHandler(FSdio *const instance_p, FSdioRelaxHandler relax_handler); + /* Dump all register value of SDIO instance */ void FSdioDumpRegister(uintptr base_addr); +/* Dump command and data info */ +void FSdioDumpCmdInfo(FSdioCmdData *const cmd_data); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_cmd.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_cmd.c index 0bcd30d960..8c163b40f0 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_cmd.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_cmd.c @@ -14,7 +14,7 @@ * FilePath: fsdio_cmd.c * Date: 2022-06-01 14:23:59 * LastEditTime: 2022-06-01 14:24:00 - * Description:  This files is for SDIO command related function + * Description:  This file is for SDIO command related function * * Modify History: * Ver   Who        Date         Changes @@ -29,6 +29,7 @@ #include "ftypes.h" #include "fcache.h" +#include "fswap.h" #include "fsdio_hw.h" #include "fsdio.h" @@ -36,6 +37,7 @@ /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ +#define FSDIO_EXT_APP_CMD 55U /***************** Macros (Inline Functions) Definitions *********************/ #define FSDIO_DEBUG_TAG "FSDIO-CMD" @@ -57,14 +59,21 @@ FError FSdioSendPrivateCmd(uintptr base_addr, u32 cmd, u32 arg) { reg_val = FSDIO_READ_REG(base_addr, FSDIO_STATUS_OFFSET); if (--retries <= 0) + { break; + } } while (FSDIO_STATUS_DATA_BUSY & reg_val); if (retries <= 0) + { return FSDIO_ERR_BUSY; + } FSDIO_WRITE_REG(base_addr, FSDIO_CMD_ARG_OFFSET, arg); + + FSDIO_DATA_BARRIER(); /* drain writebuffer */ + FSDIO_WRITE_REG(base_addr, FSDIO_CMD_OFFSET, FSDIO_CMD_START | cmd); retries = FSDIO_TIMEOUT; @@ -72,9 +81,11 @@ FError FSdioSendPrivateCmd(uintptr base_addr, u32 cmd, u32 arg) { reg_val = FSDIO_READ_REG(base_addr, FSDIO_CMD_OFFSET); if (--retries <= 0) + { break; + } } - while (FSDIO_CMD_START & reg_val); + while (FSDIO_CMD_START & reg_val); /* wait until command send done */ return (retries <= 0) ? FSDIO_ERR_TIMEOUT : FSDIO_SUCCESS; } @@ -136,7 +147,9 @@ FError FSdioTransferCmd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) raw_cmd |= FSDIO_CMD_INDX_SET(cmd_data_p->cmdidx); - FSDIO_DEBUG("============[CMD-%d]@0x%x begin ============", cmd_data_p->cmdidx, base_addr); + FSDIO_DEBUG("============[%s-%d]@0x%x begin ============", + (FSDIO_EXT_APP_CMD == instance_p->prev_cmd) ? "ACMD" : "CMD", cmd_data_p->cmdidx, + base_addr); FSDIO_DEBUG(" cmd: 0x%x", raw_cmd); FSDIO_DEBUG(" arg: 0x%x", cmd_data_p->cmdarg); @@ -144,11 +157,31 @@ FError FSdioTransferCmd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) FSdioSetInterruptMask(instance_p, FSDIO_GENERAL_INTR, FSDIO_INTS_CMD_MASK, TRUE); - FSdioSendPrivateCmd(base_addr, raw_cmd, cmd_data_p->cmdarg); + ret = FSdioSendPrivateCmd(base_addr, raw_cmd, cmd_data_p->cmdarg); FSDIO_INFO("cmd send done ..."); return ret; } +static void FSdioFlipByteOrder(u32 *response, fsize_t size) +{ + /* + swap response and convert byte order + resp[0] = bswap32(resp[3]) + resp[1] = bswap32(resp[2]) + resp[2] = bswap32(resp[1]) + resp[3] = bswap32(resp[0]) + */ + FASSERT(size % (2 * sizeof(u32)) == 0); + const fsize_t n_words = size / sizeof(uint32_t); + for (int i = 0; i < (int)n_words / 2; ++i) + { + u32 left = __builtin_bswap32(response[i]); + u32 right = __builtin_bswap32(response[n_words - i - 1]); + response[i] = right; + response[n_words - i - 1] = left; + } +} + /** * @name: FSdioGetCmdResponse * @msg: Get cmd response and received data after wait poll status or interrupt signal @@ -167,7 +200,7 @@ FError FSdioGetCmdResponse(FSdio *const instance_p, FSdioCmdData *const cmd_data if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return FSDIO_ERR_NOT_INIT; } @@ -188,6 +221,15 @@ FError FSdioGetCmdResponse(FSdio *const instance_p, FSdioCmdData *const cmd_data cmd_data_p->response[1] = FSDIO_READ_REG(base_addr, FSDIO_RESP1_OFFSET); cmd_data_p->response[2] = FSDIO_READ_REG(base_addr, FSDIO_RESP2_OFFSET); cmd_data_p->response[3] = FSDIO_READ_REG(base_addr, FSDIO_RESP3_OFFSET); + + /* according to SD spec. 136 bits R2 is send-back in reverse order and big-end, + some SD protocol will do this reverse and ntol itself, other do not, + filp_resp_byte_order is to compilant with those not */ + if (instance_p->config.filp_resp_byte_order) + { + FSdioFlipByteOrder(cmd_data_p->response, sizeof(u32) * 4); + } + FSDIO_DEBUG(" resp: 0x%x-0x%x-0x%x-0x%x", cmd_data_p->response[0], cmd_data_p->response[1], cmd_data_p->response[2], cmd_data_p->response[3]); @@ -195,16 +237,23 @@ FError FSdioGetCmdResponse(FSdio *const instance_p, FSdioCmdData *const cmd_data else { cmd_data_p->response[0] = FSDIO_READ_REG(base_addr, FSDIO_RESP0_OFFSET); + cmd_data_p->response[1] = 0U; + cmd_data_p->response[2] = 0U; + cmd_data_p->response[3] = 0U; FSDIO_DEBUG(" resp: 0x%x", cmd_data_p->response[0]); } } cmd_data_p->success = TRUE; /* cmd / data transfer finished successful */ - FSDIO_DEBUG("============[CMD-%d]@0x%x end ============", cmd_data_p->cmdidx, base_addr); + FSDIO_DEBUG("============[%s-%d]@0x%x end ============", + (FSDIO_EXT_APP_CMD == instance_p->prev_cmd) ? "ACMD" : "CMD", + cmd_data_p->cmdidx, base_addr); /* disable related interrupt */ FSdioSetInterruptMask(instance_p, FSDIO_GENERAL_INTR, FSDIO_INTS_CMD_MASK | FSDIO_INTS_DATA_MASK, FALSE); FSdioSetInterruptMask(instance_p, FSDIO_IDMA_INTR, FSDIO_DMAC_INTS_MASK, FALSE); + instance_p->prev_cmd = cmd_data_p->cmdidx; /* record previous command */ + return ret; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_dma.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_dma.c index 9fc1507d39..549f48652a 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_dma.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_dma.c @@ -14,7 +14,7 @@ * FilePath: fsdio_dma.c * Date: 2022-06-01 14:21:41 * LastEditTime: 2022-06-01 14:21:42 - * Description:  This files is for DMA related function implementation + * Description:  This file is for DMA related function implementation * * Modify History: * Ver   Who        Date         Changes @@ -29,7 +29,6 @@ #include "fassert.h" #include "ftypes.h" -#include "fcache.h" #include "fsdio_hw.h" #include "fsdio.h" @@ -47,6 +46,7 @@ /************************** Function Prototypes ******************************/ extern FError FSdioTransferCmd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); +extern FError FSdioPollWaitBusyCard(FSdio *const instance_p); /*****************************************************************************/ /** @@ -101,7 +101,7 @@ static FError FSdioSetupDMADescriptor(FSdio *const instance_p, FSdioData *data_p if (buf_num > instance_p->desc_list.desc_num) { - FSDIO_ERROR("descriptor is short for transfer %d < %d", + FSDIO_ERROR("Descriptor is too short to transfer %d < %d.", instance_p->desc_list.desc_num, buf_num); return FSDIO_ERR_SHORT_BUF; } @@ -109,7 +109,7 @@ static FError FSdioSetupDMADescriptor(FSdio *const instance_p, FSdioData *data_p memset((void *)instance_p->desc_list.first_desc, 0, sizeof(FSdioIDmaDesc) * instance_p->desc_list.desc_num); - FSDIO_INFO("%d of descriptor in use", buf_num); + FSDIO_INFO("%d of descriptor is in using.", buf_num); for (loop = 0U; loop < buf_num; loop++) { cur_desc = &(instance_p->desc_list.first_desc[loop]); @@ -127,6 +127,12 @@ static FError FSdioSetupDMADescriptor(FSdio *const instance_p, FSdioData *data_p /* set data buffer for transfer */ buff_addr = (uintptr)data_p->buf + (uintptr)(loop * data_p->blksz); + if (buff_addr % data_p->blksz) /* make sure buffer aligned and not cross page boundary */ + { + FSDIO_ERROR("Data buffer 0x%x do not align.", buff_addr); + return FSDIO_ERR_DMA_BUF_UNALIGN; + } + #ifdef __aarch64__ cur_desc->addr_hi = UPPER_32_BITS(buff_addr); cur_desc->addr_lo = LOWER_32_BITS(buff_addr); @@ -137,6 +143,12 @@ static FError FSdioSetupDMADescriptor(FSdio *const instance_p, FSdioData *data_p /* set address of next descriptor entry, NULL for last entry */ desc_addr = is_last ? 0U : (uintptr)&instance_p->desc_list.first_desc[loop + 1]; + if (desc_addr % sizeof(FSdioIDmaDesc)) /* make sure dma descriptor aligned and not cross page boundary */ + { + FSDIO_ERROR("dma descriptor 0x%x do not align.", desc_addr); + return FSDIO_ERR_DMA_BUF_UNALIGN; + } + #ifdef __aarch64__ cur_desc->desc_hi = UPPER_32_BITS(desc_addr); cur_desc->desc_lo = LOWER_32_BITS(desc_addr); @@ -147,8 +159,7 @@ static FError FSdioSetupDMADescriptor(FSdio *const instance_p, FSdioData *data_p } /* flush cache of descripor list and transfer buffer */ - FCacheDCacheFlushRange((uintptr)instance_p->desc_list.first_desc, sizeof(FSdioIDmaDesc) * instance_p->desc_list.desc_num); - FCacheDCacheFlushRange((uintptr)data_p->buf, data_p->datalen); + FSDIO_DATA_BARRIER(); FSdioDumpDMADescriptor(instance_p, buf_num); return FSDIO_SUCCESS; @@ -174,9 +185,13 @@ static FError FSdioDMATransferData(FSdio *const instance_p, FSdioData *data_p) /* fill transfer buffer to DMA descriptor */ ret = FSdioSetupDMADescriptor(instance_p, data_p); if (FSDIO_SUCCESS != ret) + { return ret; + } - FSDIO_INFO("descriptor@%p, trans bytes: %d, block size: %d", + FSDIO_DATA_BARRIER(); + + FSDIO_INFO("Descriptor@%p, trans bytes: %d, block size: %d", instance_p->desc_list.first_desc, data_p->datalen, data_p->blksz); @@ -207,29 +222,40 @@ FError FSdioDMATransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return FSDIO_ERR_NOT_INIT; } if (FSDIO_IDMA_TRANS_MODE != instance_p->config.trans_mode) { - FSDIO_ERROR("device is not configure in DMA transfer mode"); + FSDIO_ERROR("Device is not configure in DMA transfer mode."); return FSDIO_ERR_INVALID_STATE; } /* for removable media, check if card exists */ if ((FALSE == instance_p->config.non_removable) && - (FALSE == FSdioCheckIfCardExists(base_addr))) + (FALSE == FSdioCheckIfCardExists(base_addr))) { - FSDIO_ERROR("card not detected !!!"); + FSDIO_ERROR("Card is not detected !!!"); return FSDIO_ERR_NO_CARD; } + /* wait previous command finished and card not busy */ + ret = FSdioPollWaitBusyCard(instance_p); + if (FSDIO_SUCCESS != ret) + { + return ret; + } + + FSDIO_WRITE_REG(base_addr, FSDIO_RAW_INTS_OFFSET, 0xffffe); + /* reset fifo and DMA before transfer */ - FSDIO_SET_BIT(base_addr, FSDIO_CNTRL_OFFSET, FSDIO_CNTRL_FIFO_RESET | FSDIO_CNTRL_DMA_RESET); + ret = FSdioResetCtrl(base_addr, FSDIO_CNTRL_FIFO_RESET | FSDIO_CNTRL_DMA_RESET); if (FSDIO_SUCCESS != ret) + { return ret; + } /* enable use of DMA */ FSDIO_SET_BIT(base_addr, FSDIO_CNTRL_OFFSET, FSDIO_CNTRL_USE_INTERNAL_DMAC); @@ -257,7 +283,7 @@ FError FSdioDMATransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) * @param {FSdioCmdData} *cmd_data_p, contents of transfer command and data * @param {FSdioRelaxHandler} relax, handler of relax when wait busy */ -FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax) +FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) { FASSERT(instance_p); FASSERT(cmd_data_p); @@ -266,65 +292,56 @@ FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data int delay; const boolean read = cmd_data_p->flag & FSDIO_CMD_FLAG_READ_DATA; uintptr base_addr = instance_p->config.base_addr; + const u32 wait_bits = (NULL == cmd_data_p->data_p) ? FSDIO_INT_CMD_BIT : (FSDIO_INT_CMD_BIT | FSDIO_INT_DTO_BIT); if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return FSDIO_ERR_NOT_INIT; } if (FSDIO_IDMA_TRANS_MODE != instance_p->config.trans_mode) { - FSDIO_ERROR("device is not configure in DMA transfer mode"); + FSDIO_ERROR("Device is not configure in DMA transfer mode."); return FSDIO_ERR_INVALID_STATE; } - /* wait command done or timeout */ + /* wait command done or data timeout */ delay = FSDIO_TIMEOUT; do { reg_val = FSdioGetRawStatus(base_addr); - if (relax) - relax(); - } - while (!(FSDIO_INT_CMD_BIT & reg_val) && (--delay > 0)); - if (!(FSDIO_INT_CMD_BIT & reg_val) && (delay <= 0)) + if (delay % 1000 == 0) + { + FSDIO_DEBUG("reg_val = 0x%x", reg_val); + } + + if (instance_p->relax_handler) + { + instance_p->relax_handler(); + } + } + while (((wait_bits & reg_val) != wait_bits) && (--delay > 0)); + + /* clear status to ack data done */ + FSdioClearRawStatus(base_addr); + + if (((wait_bits & reg_val) != wait_bits) && (delay <= 0)) { - FSDIO_ERROR("wait cmd done timeout, raw ints: 0x%x", reg_val); + FSDIO_ERROR("Wait cmd done timeout, raw ints: 0x%x.", reg_val); return FSDIO_ERR_CMD_TIMEOUT; } if (NULL != cmd_data_p->data_p) /* wait data transfer done or timeout */ { - delay = FSDIO_TIMEOUT; - do - { - reg_val = FSDIO_READ_REG(base_addr, FSDIO_RAW_INTS_OFFSET); - if (relax) - relax(); - } - while (!(FSDIO_INT_DTO_BIT & reg_val) && (--delay > 0)); - - /* clear status to ack data done */ - FSdioClearRawStatus(base_addr); - - if (!(FSDIO_INT_DTO_BIT & reg_val) && (delay <= 0)) - { - FSDIO_ERROR("wait DMA transfer timeout, raw ints: 0x%x", reg_val); - return FSDIO_ERR_TRANS_TIMEOUT; - } - /* invalidate cache of transfer buffer */ if (read) { - FCacheDCacheInvalidateRange((uintptr)cmd_data_p->data_p, cmd_data_p->data_p->datalen); + FSDIO_DATA_BARRIER(); } } - /* clear status to ack cmd done */ - FSdioClearRawStatus(base_addr); - if (FSDIO_SUCCESS == ret) { ret = FSdioGetCmdResponse(instance_p, cmd_data_p); @@ -349,13 +366,13 @@ FError FSdioSetIDMAList(FSdio *const instance_p, volatile FSdioIDmaDesc *desc, u if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return FSDIO_ERR_NOT_INIT; } if (FSDIO_IDMA_TRANS_MODE != instance_p->config.trans_mode) { - FSDIO_ERROR("device is not configure in DMA transfer mode"); + FSDIO_ERROR("Device is not configure in DMA transfer mode."); return FSDIO_ERR_INVALID_STATE; } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_g.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_g.c index 78b00cc0e1..c7bdf08f2b 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_g.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_g.c @@ -14,7 +14,7 @@ * FilePath: fsdio_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:37:44 - * Description:  This files is for static init + * Description:  This file is for static init * * Modify History: * Ver   Who        Date         Changes @@ -40,26 +40,28 @@ /************************** Variable Definitions *****************************/ -const FSdioConfig FSDIO_CONFIG_TBL[FSDIO_HOST_INSTANCE_NUM] = +const FSdioConfig FSDIO_CONFIG_TBL[FSDIO_NUM] = { - [FSDIO_HOST_INSTANCE_0] = + [FSDIO0_ID] = { - .instance_id = FSDIO_HOST_INSTANCE_0, - .base_addr = FSDIO_HOST_0_BASE_ADDR, - .irq_num = FSDIO_HOST_0_IRQ_NUM, + .instance_id = FSDIO0_ID, + .base_addr = FSDIO0_BASE_ADDR, + .irq_num = FSDIO0_IRQ_NUM, .trans_mode = FSDIO_IDMA_TRANS_MODE, .voltage = FSDIO_SD_3_3V_VOLTAGE, - .non_removable = FALSE + .non_removable = FALSE, + .filp_resp_byte_order = FALSE }, - [FSDIO_HOST_INSTANCE_1] = + [FSDIO1_ID] = { - .instance_id = FSDIO_HOST_INSTANCE_1, - .base_addr = FSDIO_HOST_1_BASE_ADDR, - .irq_num = FSDIO_HOST_1_IRQ_NUM, + .instance_id = FSDIO1_ID, + .base_addr = FSDIO1_BASE_ADDR, + .irq_num = FSDIO1_IRQ_NUM, .trans_mode = FSDIO_IDMA_TRANS_MODE, .voltage = FSDIO_SD_3_3V_VOLTAGE, - .non_removable = FALSE + .non_removable = FALSE, + .filp_resp_byte_order = FALSE } }; diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_hw.h b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_hw.h index a0a1a0b1b6..33a7edf193 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_hw.h @@ -14,7 +14,7 @@ * FilePath: fsdio_hw.h * Date: 2022-05-26 15:32:34 * LastEditTime: 2022-05-26 15:32:35 - * Description:  This files is for SDIO register function definition + * Description:  This file is for SDIO register function definition * * Modify History: * Ver   Who        Date         Changes @@ -23,20 +23,28 @@ * 1.1 zhugengyu 2022/5/26 modify according to tech manual. */ -#ifndef DRIVERS_FSDIO_HW_H -#define DRIVERS_FSDIO_HW_H +#ifndef FSDIO_HW_H +#define FSDIO_HW_H -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ + #include "fparameters.h" #include "fio.h" #include "ftypes.h" #include "fassert.h" #include "fkernel.h" +#ifdef __aarch64__ +#include "faarch64.h" +#else +#include "fcp15.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /** @name Register Map @@ -118,8 +126,10 @@ extern "C" #define FSDIO_CLK_DRV_SET(x) SET_REG32_BITS((x), 15, 8) #define FSDIO_CLK_DIVIDER_SET(x) SET_REG32_BITS((x), 7, 0) /* 分频系数 = 2 * bit[7:0] */ #define FSDIO_CLK_DIV(samp, drv, div) FSDIO_CLK_SAMPLE_SET(samp) | \ - FSDIO_CLK_DRV_SET(drv) | \ - FSDIO_CLK_DIVIDER_SET(div) + FSDIO_CLK_DRV_SET(drv) | \ + FSDIO_CLK_DIVIDER_SET(div) + +#define FSDIO_CLK_DIVDER_GET(div_reg) GET_REG32_BITS((div_reg), 7, 0) /** @name FSDIO_CLKENA_OFFSET Register */ @@ -164,10 +174,10 @@ extern "C" #define FSDIO_INT_ALL_BITS GENMASK(16, 0) #define FSDIO_INTS_CMD_MASK (FSDIO_INT_RE_BIT | FSDIO_INT_CMD_BIT | FSDIO_INT_RCRC_BIT | \ - FSDIO_INT_RTO_BIT | FSDIO_INT_HTO_BIT | FSDIO_INT_HLE_BIT) + FSDIO_INT_RTO_BIT | FSDIO_INT_HTO_BIT | FSDIO_INT_HLE_BIT) #define FSDIO_INTS_DATA_MASK (FSDIO_INT_DTO_BIT | FSDIO_INT_DCRC_BIT | FSDIO_INT_DRTO_BIT | \ - FSDIO_INT_SBE_BCI_BIT) + FSDIO_INT_SBE_BCI_BIT) /** @name FSDIO_CMD_OFFSET Register */ @@ -362,6 +372,7 @@ enum #define FSDIO_CLR_BIT(addr, reg_off, bits) FtClearBit32((addr) + (u32)(reg_off), bits) #define FSDIO_SET_BIT(addr, reg_off, bits) FtSetBit32((addr) + (u32)(reg_off), bits) +#define FSDIO_DATA_BARRIER() WMB() /************************** Function Prototypes ******************************/ FError FSdioSendPrivateCmd(uintptr base_addr, u32 cmd, u32 arg); FError FSdioResetCtrl(uintptr base_addr, u32 reset_bits); @@ -378,9 +389,13 @@ static inline void FSdioSetClock(uintptr base_addr, boolean enable) { u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_CLKENA_OFFSET); if (enable) + { reg_val |= FSDIO_CLKENA_CCLK_ENABLE; + } else + { reg_val &= ~FSDIO_CLKENA_CCLK_ENABLE; + } FSDIO_WRITE_REG(base_addr, FSDIO_CLKENA_OFFSET, reg_val); } @@ -388,9 +403,13 @@ static inline void FSdioSetPower(uintptr base_addr, boolean enable) { u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_PWREN_OFFSET); if (enable) + { reg_val |= FSDIO_PWREN_ENABLE; + } else + { reg_val &= ~FSDIO_PWREN_ENABLE; + } FSDIO_WRITE_REG(base_addr, FSDIO_PWREN_OFFSET, reg_val); } @@ -398,9 +417,13 @@ static inline void FSdioSetExtClock(uintptr base_addr, boolean enable) { u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET); if (enable) + { reg_val |= FSDIO_UHS_EXT_CLK_ENA; + } else + { reg_val &= ~FSDIO_UHS_EXT_CLK_ENA; + } FSDIO_WRITE_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET, reg_val); } @@ -408,9 +431,13 @@ static inline void FSdioSetVoltage1_8V(uintptr base_addr, boolean v1_8) { u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_OFFSET); if (v1_8) + { reg_val |= FSDIO_UHS_REG_VOLT_180; + } else - reg_val &= ~FSDIO_UHS_REG_VOLT_180; /* 3.3v */ + { + reg_val &= ~FSDIO_UHS_REG_VOLT_180; /* 3.3v */ + } FSDIO_WRITE_REG(base_addr, FSDIO_UHS_REG_OFFSET, reg_val); } @@ -526,18 +553,18 @@ static inline void FSdioSetBusWidth(uintptr base_addr, u32 width) switch (width) { - case 1: - reg_val = FSDIO_CARD0_WIDTH2_1BIT; - break; - case 4: - reg_val = FSDIO_CARD0_WIDTH2_4BIT; - break; - case 8: - reg_val = FSDIO_CARD0_WIDTH1_8BIT; - break; - default: - FASSERT_MSG(0, "invalid bus width %d", width); - break; + case 1: + reg_val = FSDIO_CARD0_WIDTH2_1BIT; + break; + case 4: + reg_val = FSDIO_CARD0_WIDTH2_4BIT; + break; + case 8: + reg_val = FSDIO_CARD0_WIDTH1_8BIT; + break; + default: + FASSERT_MSG(0, "invalid bus width %d", width); + break; } FSDIO_WRITE_REG(base_addr, FSDIO_CTYPE_OFFSET, reg_val); diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_intr.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_intr.c index 333795b2db..4cd6997634 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_intr.c @@ -14,7 +14,7 @@ * FilePath: fsdio_intr.c * Date: 2022-06-01 15:08:58 * LastEditTime: 2022-06-01 15:08:58 - * Description:  This files is for SDIO interrupt related function implementation + * Description:  This file is for SDIO interrupt related function implementation * * Modify History: * Ver   Who        Date         Changes @@ -42,18 +42,18 @@ #define FSDIO_INFO(format, ...) FT_DEBUG_PRINT_I(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) #define FSDIO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSDIO_CALL_EVT_HANDLER(instance_p, evt) \ +#define FSDIO_CALL_EVT_HANDLER(instance_p, evt, status, dmac_status) \ if (instance_p->evt_handlers[evt]) \ { \ - instance_p->evt_handlers[evt](instance_p, instance_p->evt_args[evt]); \ + instance_p->evt_handlers[evt](instance_p, instance_p->evt_args[evt], status, dmac_status); \ } static const u32 cmd_err_ints_mask = FSDIO_INT_RTO_BIT | FSDIO_INT_RCRC_BIT | FSDIO_INT_RE_BIT | FSDIO_INT_DCRC_BIT | FSDIO_INT_DRTO_BIT | - FSDIO_INT_SBE_BCI_BIT | FSDIO_INT_HLE_BIT; + FSDIO_INT_SBE_BCI_BIT; static const u32 dmac_err_ints_mask = FSDIO_DMAC_INT_ENA_FBE | FSDIO_DMAC_INT_ENA_DU | - FSDIO_DMAC_INT_ENA_AIS; + FSDIO_DMAC_INT_ENA_NIS | FSDIO_DMAC_INT_ENA_AIS; /************************** Function Prototypes ******************************/ /*****************************************************************************/ @@ -73,7 +73,7 @@ u32 FSdioGetInterruptMask(FSdio *const instance_p, FSdioIntrType type) if (0 == instance_p->config.base_addr) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return mask; } @@ -106,7 +106,7 @@ void FSdioSetInterruptMask(FSdio *const instance_p, FSdioIntrType type, u32 set_ if (0 == instance_p->config.base_addr) { - FSDIO_ERROR("device is not yet initialized!!!"); + FSDIO_ERROR("Device is not yet initialized!!!"); return; } @@ -153,9 +153,9 @@ void FSdioInterruptHandler(s32 vector, void *param) dmac_evt_mask = FSDIO_READ_REG(base_addr, FSDIO_DMAC_INT_EN_OFFSET); if (!(events & FSDIO_INT_ALL_BITS) && - !(dmac_events & FSDIO_DMAC_STATUS_ALL_BITS)) + !(dmac_events & FSDIO_DMAC_STATUS_ALL_BITS)) { - FSDIO_DEBUG("irq exit with no action"); + FSDIO_DEBUG("irq exit with no action."); return; /* no interrupt status */ } @@ -163,11 +163,12 @@ void FSdioInterruptHandler(s32 vector, void *param) FSDIO_DEBUG("events:0x%x,mask:0x%x,dmac_events:%x,dmac_mask:0x%x", events, event_mask, dmac_events, dmac_evt_mask); + /* clear interrupt status */ FSDIO_WRITE_REG(base_addr, FSDIO_RAW_INTS_OFFSET, events); FSDIO_WRITE_REG(base_addr, FSDIO_DMAC_STATUS_OFFSET, dmac_events); if (((events & event_mask) == 0) && - ((dmac_events & dmac_evt_mask == 0))) + ((dmac_events & dmac_evt_mask == 0))) { return; /* no need to handle interrupt */ } @@ -176,24 +177,7 @@ void FSdioInterruptHandler(s32 vector, void *param) if (((events & event_mask) & FSDIO_INT_CD_BIT) && (FALSE == instance_p->config.non_removable)) { FSDIO_DEBUG("sd status changed here ! status:[%d]", FSDIO_READ_REG(base_addr, FSDIO_CARD_DETECT_OFFSET)); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CARD_DETECTED); - } - - if ((events & FSDIO_INT_DTO_BIT) && (events & FSDIO_INT_CMD_BIT)) /* handle cmd && data done */ - { - FSDIO_DEBUG("cmd and data over"); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CMD_DONE); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_DATA_DONE); - } - else if (events & FSDIO_INT_CMD_BIT) /* handle cmd done */ - { - FSDIO_DEBUG("cmd over"); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CMD_DONE); - } - else if (events & FSDIO_INT_DTO_BIT) /* handle data done */ - { - FSDIO_DEBUG("data over"); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_DATA_DONE); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CARD_DETECTED, events, dmac_events); } /* handle error state */ @@ -201,7 +185,24 @@ void FSdioInterruptHandler(s32 vector, void *param) { FSDIO_ERROR("ERR:events:0x%x,mask:0x%x,dmac_evts:0x%x,dmac_mask:0x%x", events, event_mask, dmac_events, dmac_evt_mask); - FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_ERR_OCCURE); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_ERR_OCCURE, events, dmac_events); + } + + if ((events & FSDIO_INT_DTO_BIT) && (events & FSDIO_INT_CMD_BIT)) /* handle cmd && data done */ + { + FSDIO_DEBUG("Cmd and data over !!!"); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CMD_DONE, events, dmac_events); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_DATA_DONE, events, dmac_events); + } + else if (events & FSDIO_INT_CMD_BIT) /* handle cmd done */ + { + FSDIO_DEBUG("Cmd over !!!"); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_CMD_DONE, events, dmac_events); + } + else if (events & FSDIO_INT_DTO_BIT) /* handle data done */ + { + FSDIO_DEBUG("Data over !!!"); + FSDIO_CALL_EVT_HANDLER(instance_p, FSDIO_EVT_DATA_DONE, events, dmac_events); } return; diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_pio.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_pio.c index dfe4f1b5a9..488f10be0c 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_pio.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_pio.c @@ -14,7 +14,7 @@ * FilePath: fsdio_pio.c * Date: 2022-06-01 14:21:47 * LastEditTime: 2022-06-01 14:21:47 - * Description:  This files is for PIO transfer related function implementation + * Description:  This file is for PIO transfer related function implementation * * Modify History: * Ver   Who        Date         Changes @@ -28,8 +28,6 @@ #include "fassert.h" #include "ftypes.h" -#include "fcache.h" - #include "fsdio_hw.h" #include "fsdio.h" @@ -46,6 +44,7 @@ /************************** Function Prototypes ******************************/ extern FError FSdioTransferCmd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p); +extern FError FSdioPollWaitBusyCard(FSdio *const instance_p); /*****************************************************************************/ /** @@ -64,13 +63,6 @@ static FError FSdioPIOWriteData(FSdio *const instance_p, FSdioData *data_p) const u32 wr_times = data_p->datalen / sizeof(u32); /* u8 --> u32 */ u32 *wr_buf = (u32 *)data_p->buf; - /* while in PIO mode, max data transferred is 0x800 */ - if (data_p->datalen > FSDIO_MAX_FIFO_CNT) - { - FSDIO_ERROR("Fifo do not support write more than 0x%x", FSDIO_MAX_FIFO_CNT); - return FSDIO_ERR_NOT_SUPPORT; - } - /* write fifo data */ FSDIO_WRITE_REG(base_addr, FSDIO_CMD_OFFSET, FSDIO_CMD_DAT_WRITE); for (loop = 0; loop < wr_times; loop++) @@ -100,7 +92,7 @@ FError FSdioPIOReadData(FSdio *const instance_p, FSdioData *data_p) /* while in PIO mode, max data transferred is 0x800 */ if (data_p->datalen > FSDIO_MAX_FIFO_CNT) { - FSDIO_ERROR("Fifo do not support write more than 0x%x", FSDIO_MAX_FIFO_CNT); + FSDIO_ERROR("Fifo do not support writing more than 0x%x.", FSDIO_MAX_FIFO_CNT); return FSDIO_ERR_NOT_SUPPORT; } @@ -138,27 +130,43 @@ FError FSdioPIOTransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) if (FSDIO_PIO_TRANS_MODE != instance_p->config.trans_mode) { - FSDIO_ERROR("device is not configure in PIO transfer mode"); + FSDIO_ERROR("device is not configure in PIO transfer mode."); return FSDIO_ERR_INVALID_STATE; } /* for removable media, check if card exists */ if ((FALSE == instance_p->config.non_removable) && - (FALSE == FSdioCheckIfCardExists(base_addr))) + (FALSE == FSdioCheckIfCardExists(base_addr))) { - FSDIO_ERROR("card not detected !!!"); + FSDIO_ERROR("card is not detected !!!"); return FSDIO_ERR_NO_CARD; } + /* wait previous command finished and card not busy */ + ret = FSdioPollWaitBusyCard(instance_p); + if (FSDIO_SUCCESS != ret) + { + return ret; + } + /* reset fifo and not use DMA */ FSDIO_CLR_BIT(base_addr, FSDIO_CNTRL_OFFSET, FSDIO_CNTRL_USE_INTERNAL_DMAC); ret = FSdioResetCtrl(base_addr, FSDIO_CNTRL_FIFO_RESET); if (FSDIO_SUCCESS != ret) + { return ret; + } FSDIO_CLR_BIT(base_addr, FSDIO_BUS_MODE_OFFSET, FSDIO_BUS_MODE_DE); if (NULL != cmd_data_p->data_p) { + /* while in PIO mode, max data transferred is 0x800 */ + if (cmd_data_p->data_p->datalen > FSDIO_MAX_FIFO_CNT) + { + FSDIO_ERROR("Fifo do not support writing more than 0x%x.", FSDIO_MAX_FIFO_CNT); + return FSDIO_ERR_NOT_SUPPORT; + } + /* set transfer data length and block size */ FSdioSetTransBytes(base_addr, cmd_data_p->data_p->datalen); FSdioSetBlockSize(base_addr, cmd_data_p->data_p->blksz); @@ -166,8 +174,8 @@ FError FSdioPIOTransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) if (FALSE == read) /* if need to write, write to fifo before send command */ { /* invalide buffer for data to write */ - FCacheDCacheInvalidateRange((uintptr)cmd_data_p->data_p->buf, - cmd_data_p->data_p->datalen); + + FSDIO_DATA_BARRIER(); ret = FSdioPIOWriteData(instance_p, cmd_data_p->data_p); } @@ -189,7 +197,7 @@ FError FSdioPIOTransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) * @param {FSdioCmdData} *cmd_data_p, contents of transfer command and data * @param {FSdioRelaxHandler} relax, handler of relax when wait busy */ -FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p, FSdioRelaxHandler relax) +FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p) { FASSERT(instance_p); FASSERT(cmd_data_p); @@ -208,7 +216,7 @@ FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data if (FSDIO_PIO_TRANS_MODE != instance_p->config.trans_mode) { - FSDIO_ERROR("device is not configure in PIO transfer mode"); + FSDIO_ERROR("device is not configure in PIO transfer mode."); return FSDIO_ERR_INVALID_STATE; } @@ -217,8 +225,10 @@ FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data do { reg_val = FSdioGetRawStatus(base_addr); - if (relax) - relax(); + if (instance_p->relax_handler) + { + instance_p->relax_handler(); + } } while (!(FSDIO_INT_CMD_BIT & reg_val) && (--delay > 0)); @@ -236,8 +246,10 @@ FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data do { reg_val = FSdioGetRawStatus(base_addr); - if (relax) - relax(); + if (instance_p->relax_handler) + { + instance_p->relax_handler(); + } } while (!(FSDIO_INT_DTO_BIT & reg_val) && (--delay > 0)); @@ -249,7 +261,7 @@ FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data if (!(FSDIO_INT_DTO_BIT & reg_val) && (delay <= 0)) { - FSDIO_ERROR("wait PIO transfer timeout, raw ints: 0x%x", reg_val); + FSDIO_ERROR("wait PIO transfer timeout, raw ints: 0x%x.", reg_val); return FSDIO_ERR_TRANS_TIMEOUT; } } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_selftest.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_selftest.c index 34e8b8520a..cf962e2cd1 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_selftest.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_selftest.c @@ -14,7 +14,7 @@ * FilePath: fsdio_selftest.c * Date: 2022-06-02 11:49:44 * LastEditTime: 2022-06-02 11:49:45 - * Description:  This files is for SDIO self-test function + * Description:  This file is for SDIO self-test function * * Modify History: * Ver   Who        Date         Changes @@ -100,4 +100,33 @@ void FSdioDumpRegister(uintptr base_addr) FSDIO_DUMPER(base_addr, FSDIO_UHS_REG_EXT_OFFSET, "uhsregext"); FSDIO_DUMPER(base_addr, FSDIO_EMMC_DDR_REG_OFFSET, "emmcddr"); FSDIO_DUMPER(base_addr, FSDIO_ENABLE_SHIFT_OFFSET, "enableshift"); +} + +/** + * @name: FSdioDumpCmdInfo + * @msg: Dump command and data info + * @return {NONE} + * @param {FSdioCmdData *const} cmd_data, info data of SD command and data + */ +void FSdioDumpCmdInfo(FSdioCmdData *const cmd_data) +{ + FSDIO_DEBUG("cmd struct @%p", cmd_data); + FSDIO_DEBUG(" opcode: %d", cmd_data->cmdidx); + FSDIO_DEBUG(" arg: 0x%x", cmd_data->cmdarg); + FSDIO_DEBUG(" resp@%p: 0x%x 0x%x 0x%x 0x%x", + cmd_data->response, + cmd_data->response[0], + cmd_data->response[1], + cmd_data->response[2], + cmd_data->response[3]); + FSDIO_DEBUG(" flag: 0x%x", cmd_data->flag); + FSDIO_DEBUG(" data @%p", cmd_data->data_p); + + if (cmd_data->data_p) + { + FSDIO_DEBUG(" buf: %p, len: %d", cmd_data->data_p->buf, + cmd_data->data_p->datalen); + FSDIO_DEBUG(" blk sz: %d", cmd_data->data_p->blksz); + FSDIO_DEBUG(" blk cnt: %d", cmd_data->data_p->blkcnt); + } } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_sinit.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_sinit.c index 3111024e72..8724184156 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio_sinit.c @@ -14,7 +14,7 @@ * FilePath: fsdio_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:48:41 - * Description:  This files is for static init + * Description:  This file is for static init * * Modify History: * Ver   Who        Date         Changes @@ -37,7 +37,7 @@ /************************** Variable Definitions *****************************/ -extern const FSdioConfig FSDIO_CONFIG_TBL[FSDIO_HOST_INSTANCE_NUM]; +extern const FSdioConfig FSDIO_CONFIG_TBL[FSDIO_NUM]; /************************** Function Prototypes ******************************/ /** @@ -51,7 +51,7 @@ const FSdioConfig *FSdioLookupConfig(u32 instance_id) const FSdioConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)FSDIO_HOST_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FSDIO_NUM; index++) { if (FSDIO_CONFIG_TBL[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.c index cb15f01464..0fea8b152b 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.c @@ -14,7 +14,8 @@ * FilePath: fsdmmc.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:55:23 - * Description:  This files is for + * Description:  This file is for functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes @@ -31,7 +32,7 @@ #include "ftypes.h" #include "fdebug.h" -#include "fcache.h" + #include "fsleep.h" #include "fsdmmc_hw.h" @@ -83,7 +84,7 @@ FError FSdmmcCfgInitialize(FSdmmc *instance_p, const FSdmmcConfig *input_config_ */ if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FSDMMC_WARN("device is already initialized!!!"); + FSDMMC_WARN("Device is already initialized!!!"); } /* @@ -101,7 +102,7 @@ FError FSdmmcCfgInitialize(FSdmmc *instance_p, const FSdmmcConfig *input_config_ */ if (!FSdmmcCheckIfCardExists(base_addr)) { - FSDMMC_ERROR("storage device not found !!! 0x%x", base_addr); + FSDMMC_ERROR("Storage device not found !!! 0x%x", base_addr); return FSDMMC_ERR_CARD_NO_FOUND; } @@ -110,7 +111,9 @@ FError FSdmmcCfgInitialize(FSdmmc *instance_p, const FSdmmcConfig *input_config_ */ ret = FSdmmcReset(base_addr); if (FSDMMC_SUCCESS == ret) + { instance_p->is_ready = FT_COMPONENT_IS_READY; + } return ret; } @@ -149,14 +152,22 @@ u32 FSdmmcMakeRawCmd(FSdmmcCmd *cmd_p) raw_cmd |= FSDMMC_CMD_SETTING_CMDI(cmd_p->cmdidx); if (cmd_p->flag & FSDMMC_CMD_FLAG_ADTC) - raw_cmd |= FSDMMC_CMD_SETTING_TRTY(0b10); /* adtc指令 */ + { + raw_cmd |= FSDMMC_CMD_SETTING_TRTY(0b10); /* adtc指令 */ + } if (0 == (cmd_p->flag & FSDMMC_CMD_FLAG_EXP_RESP)) + { raw_cmd |= FSDMMC_CMD_NO_RESP; + } else if (cmd_p->flag & FSDMMC_CMD_FLAG_EXP_LONG_RESP) + { raw_cmd |= FSDMMC_CMD_RESP_136_BIT; + } else + { raw_cmd |= FSDMMC_CMD_RESP_48_BIT; + } return raw_cmd; } @@ -175,7 +186,9 @@ static FError FSdmmcWaitCmdEnd(uintptr base_addr, FSdmmcCmd *cmd_p) ret = FSdmmcWaitStatus(base_addr, FSDMMC_TIMEOUT); if (FSDMMC_SUCCESS != ret) + { return ret; + } if (cmd_p->flag & FSDMMC_CMD_FLAG_EXP_RESP) { @@ -269,22 +282,24 @@ FError FSdmmcSendData(uintptr base_addr, boolean read, FSdmmcCmd *cmd_p) if ((dat_p->datalen >= FSDMMC_DMA_ADDR_ALIGN) && (dat_p->datalen % FSDMMC_DMA_ADDR_ALIGN != 0)) { - FSDMMC_ERROR("invalid size: total = %d ", dat_p->datalen); + FSDMMC_ERROR("Invalid size: total = %d.", dat_p->datalen); return FSDMMC_ERR_INVALID_BUF; } if (((uintptr)(dat_p->buf) % FSDMMC_DMA_ADDR_ALIGN) != 0) { - FSDMMC_ERROR("buffer %p can not be used for DMA", dat_p->buf); + FSDMMC_ERROR("Buffer %p can not be used for DMA.", dat_p->buf); return FSDMMC_ERR_INVALID_BUF; } card_addr = cmd_p->cmdarg; blk_cnt = dat_p->datalen / dat_p->blksz; if (dat_p->datalen % dat_p->blksz) + { blk_cnt++; + } - FSDMMC_INFO("data len: %d, card addr: 0x%x, blk cnt: %d, is %s", + FSDMMC_INFO("Data len: %d, card addr: 0x%x, blk cnt: %d, is %s", dat_p->datalen, card_addr, blk_cnt, read ? "read" : "write"); if (read) @@ -299,7 +314,7 @@ FError FSdmmcSendData(uintptr base_addr, boolean read, FSdmmcCmd *cmd_p) else { /* invalidate write buf */ - FCacheDCacheInvalidateRange((uintptr)dat_p->buf, dat_p->datalen); + FSDMMC_DATA_BARRIER(); /* write data */ FSdmmcSetWriteDMA(base_addr, (uintptr)card_addr, blk_cnt, dat_p->buf); @@ -324,17 +339,23 @@ static FError FSdmmcTransferDataPoll(uintptr base_addr, FSdmmcCmd *cmd_p) ret = FSdmmcSendData(base_addr, read, cmd_p); if (FSDMMC_SUCCESS != ret) + { return ret; + } ret = FSdmmcWaitCmdEnd(base_addr, cmd_p); if (FSDMMC_SUCCESS != ret) + { return ret; + } ret = FSdmmcWaitDMAStatus(base_addr, read, FSDMMC_TIMEOUT); if (FSDMMC_SUCCESS != ret) + { return ret; + } - FCacheDCacheInvalidateRange((uintptr)dat_p->buf, dat_p->datalen); + FSDMMC_DATA_BARRIER(); return ret; } @@ -354,7 +375,7 @@ FError FSdmmcPollTransfer(FSdmmc *instance_p, FSdmmcCmd *cmd_data_p) if (FALSE == FSdmmcCheckIfCardExists(base_addr)) { - FSDMMC_ERROR("card not found !!! fsdio ctrl base 0x%x", base_addr); + FSDMMC_ERROR("Card not found !!! fsdio ctrl base 0x%x.", base_addr); return FSDMMC_ERR_CARD_NO_FOUND; } @@ -365,7 +386,7 @@ FError FSdmmcPollTransfer(FSdmmc *instance_p, FSdmmcCmd *cmd_data_p) ret = FSdmmcTransferDataPoll(base_addr, cmd_data_p); if (FSDMMC_SUCCESS != ret) { - FSDMMC_ERROR("trans data failed 0x%x", ret); + FSDMMC_ERROR("Transfer data failed 0x%x.", ret); return ret; } @@ -378,7 +399,7 @@ FError FSdmmcPollTransfer(FSdmmc *instance_p, FSdmmcCmd *cmd_data_p) ret = FSdmmcTransferCmdPoll(base_addr, cmd_data_p); if (FSDMMC_SUCCESS != ret) { - FSDMMC_ERROR("send cmd failed 0x%x", ret); + FSDMMC_ERROR("Send cmd failed 0x%x.", ret); return ret; } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.h b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.h index 25573e68af..7805a17679 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.h +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc.h @@ -14,7 +14,8 @@ * FilePath: fsdmmc.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:55:57 - * Description:  This files is for + * Description:  This file is for functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes @@ -22,20 +23,19 @@ * 1.0 zhugengyu 2021/12/2 init */ -#ifndef DRIVERS_MMC_FSDMMC_H -#define DRIVERS_MMC_FSDMMC_H - -#ifdef __cplusplus -extern "C" -{ -#endif - +#ifndef FSDMMC_H +#define FSDMMC_H /***************************** Include Files *********************************/ #include "ftypes.h" #include "ferror_code.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ #define FSDMMC_SUCCESS FT_SUCCESS #define FSDMMC_ERR_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 1) @@ -112,7 +112,7 @@ typedef struct u32 irq_num[FSDMMC_INTR_NUM]; } FSdmmcConfig; -typedef void (*FSdmmcEventHandler)(void *instance_p); +typedef void (*FSdmmcEventHandler)(void *args); /** * This typedef contains driver instance data. The user is required to allocate a @@ -124,6 +124,7 @@ typedef struct FSdmmcConfig config; /* Current active configs */ u32 is_ready; /* Device is initialized and ready */ FSdmmcEventHandler evt_handler[FSDMMC_EVT_NUM]; + void *evt_args[FSDMMC_EVT_NUM]; } FSdmmc; /* Device instance */ /************************** Variable Definitions *****************************/ @@ -163,7 +164,7 @@ void FSdmmcErrInterrupHandler(s32 vector, void *param); void FSdmmcDmaInterrupHandler(s32 vector, void *param); /* 注册中断事件响应函数 */ -void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler); +void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler, void *args); #ifdef __cplusplus } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.c index d2c4da00c4..08ba04333e 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.c @@ -14,7 +14,7 @@ * FilePath: fsdmmc_dma.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:49:31 - * Description:  This files is for + * Description:  This file is dma descriptor management API. * * Modify History: * Ver   Who        Date         Changes @@ -68,7 +68,7 @@ void FSdmmcSetReadDMA(uintptr base_addr, uintptr card_addr, u32 blk_cnt, void *b FSDMMC_INFO("sd card: 0x%x:0x%x ==> mem space: 0x%x:0x%x", srch, srcl, dsth, dstl); - FSDMMC_INFO("read %d blks from 0x%x", blk_cnt, card_addr); + FSDMMC_INFO("Read %d blks from 0x%x", blk_cnt, card_addr); /* DMA 复位 */ FSDMMC_SET_BIT(base_addr, FSDMMC_SOFTWARE_RESET_REG_OFFSET, FSDMMC_SOFTWARE_RESET_BDRST); @@ -82,7 +82,9 @@ void FSdmmcSetReadDMA(uintptr base_addr, uintptr card_addr, u32 blk_cnt, void *b FSdmmcClearBDInterruptStatus(base_addr); FSdmmcClearNormalInterruptStatus(base_addr); - FSDMMC_INFO("base addr: 0x%x buf_p: %p", base_addr, buf_p); + FSDMMC_INFO("Base addr: 0x%x buf_p: %p", base_addr, buf_p); + + FSDMMC_DATA_BARRIER(); /* DMA 读卡地址配置:4 个 cycle 系统低 4B-系统高 4B-SD 低 4B- SD 高 4B */ @@ -116,7 +118,7 @@ void FSdmmcSetWriteDMA(uintptr base_addr, uintptr card_addr, u32 blk_cnt, const FSDMMC_INFO("mem space: 0x%x:0x%x ==> sd card: 0x%x:0x%x", srch, srcl, dsth, dstl); - FSDMMC_INFO("write %d blks from 0x%x", blk_cnt, card_addr); + FSDMMC_INFO("Write %d blks from 0x%x", blk_cnt, card_addr); /* DMA 复位 */ FSDMMC_SET_BIT(base_addr, FSDMMC_SOFTWARE_RESET_REG_OFFSET, FSDMMC_SOFTWARE_RESET_BDRST); @@ -130,6 +132,8 @@ void FSdmmcSetWriteDMA(uintptr base_addr, uintptr card_addr, u32 blk_cnt, const FSdmmcClearBDInterruptStatus(base_addr); FSdmmcClearNormalInterruptStatus(base_addr); + FSDMMC_DATA_BARRIER(); + /* DMA 写卡地址配置:4 个 cycle 系统低 4B-系统高 4B-SD 低 4B- SD 高 4B */ FSDMMC_WRITE_REG(base_addr, FSDMMC_DAT_IN_M_TX_BD_REG_OFFSET, srcl); diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.h b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.h index 06cff5d8f4..51fb27175c 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.h +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_dma.h @@ -14,7 +14,7 @@ * FilePath: fsdmmc_dma.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:51:25 - * Description:  This files is for + * Description:  This file is dma descriptormanagement API. * * Modify History: * Ver   Who        Date         Changes @@ -22,15 +22,15 @@ * 1.0 zhugengyu 2021/12/2 init */ -#ifndef DRIVERS_MMC_FSDMMC_DMA_H -#define DRIVERS_MMC_FSDMMC_DMA_H +#ifndef FSDMMC_DMA_H +#define FSDMMC_DMA_H +/***************************** Include Files *********************************/ +#include "ftypes.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "ftypes.h" /************************** Constant Definitions *****************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_g.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_g.c index bef9e3f28d..5824c10767 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_g.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_g.c @@ -14,7 +14,8 @@ * FilePath: fsdmmc_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:53:31 - * Description:  This files is for + * Description:  This file contains a configuration table that specifies the configuration of + * the fsdmmc devices in the system. * * Modify History: * Ver   Who        Date         Changes @@ -43,17 +44,17 @@ /************************** Variable Definitions *****************************/ -const FSdmmcConfig FSDMMC_CONFIG_TBL[FSDMMC_HOST_INSTANCE_NUM] = +const FSdmmcConfig FSDMMC_CONFIG_TBL[FSDMMC_NUM] = { - [FSDMMC_HOST_INSTANCE_0] = + [FSDMMC0_ID] = { - .instance_id = FSDMMC_HOST_INSTANCE_0, /* Id of device*/ - .base_addr = FSDMMC_HOST_0_BASEADDR, + .instance_id = FSDMMC0_ID, /* Id of device*/ + .base_addr = FSDMMC0_BASE_ADDR, .irq_num = { - [FSDMMC_CMD_INTR] = FSDMMC_HOST_0_CMD_INTR_IRQ, - [FSDMMC_DMA_BD_INTR] = FSDMMC_HOST_0_DMA_INTR_IRQ, - [FSDMMC_ERROR_INTR] = FSDMMC_HOST_0_ERR_INTR_IRQ + [FSDMMC_CMD_INTR] = FSDMMC0_CMD_IRQ_NUM, + [FSDMMC_DMA_BD_INTR] = FSDMMC0_DMA_IRQ_NUM, + [FSDMMC_ERROR_INTR] = FSDMMC0_ERR_IRQ_NUM } } }; diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.c index 155f388561..ce66d24978 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.c @@ -14,7 +14,7 @@ * FilePath: fsdmmc_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:54:02 - * Description:  This files is for + * Description:  This file contains macros that can be used to access the device. * * Modify History: * Ver   Who        Date         Changes @@ -25,7 +25,6 @@ /***************************** Include Files *********************************/ #include "fassert.h" #include "fdebug.h" - #include "fsdmmc_hw.h" #include "fsdmmc.h" @@ -63,11 +62,11 @@ FError FSdmmcSoftwareReset(uintptr base_addr, int retries) reg_val = FSDMMC_READ_REG(base_addr, FSDMMC_STATUS_REG_OFFSET); } while (!(reg_val & FSDMMC_STATUS_IDIE) && - (retries-- > 0)); + (retries-- > 0)); if (!(reg_val & FSDMMC_STATUS_IDIE) && (retries <= 0)) { - FSDMMC_ERROR("software reset timeout!!! status: 0x%x", reg_val); + FSDMMC_ERROR("Software reset timeout!!! status: 0x%x", reg_val); return FSDMMC_ERR_TIMEOUT; } @@ -96,20 +95,20 @@ static const char *FSdmmcGetRespTypeStr(u32 hw_cmd) switch (FSDMMC_CMD_RESP_MASK & hw_cmd) { - case FSDMMC_CMD_NO_RESP: - str = "NONE"; - break; - case FSDMMC_CMD_RESP_136_BIT: - str = "LONG"; - break; - case FSDMMC_CMD_RESP_48_BIT: - str = "SHORT"; - break; - case FSDMMC_CMD_RESP_48_BIT_BUSY_CHECK: - str = "SHORT CHECK BUSY"; - break; - default: - FASSERT(0); + case FSDMMC_CMD_NO_RESP: + str = "NONE"; + break; + case FSDMMC_CMD_RESP_136_BIT: + str = "LONG"; + break; + case FSDMMC_CMD_RESP_48_BIT: + str = "SHORT"; + break; + case FSDMMC_CMD_RESP_48_BIT_BUSY_CHECK: + str = "SHORT CHECK BUSY"; + break; + default: + FASSERT(0); } return str; @@ -133,6 +132,8 @@ void FSdmmcSendPrivateCmd(uintptr base_addr, u32 cmd, u32 arg) /* 设置命令 */ FSDMMC_WRITE_REG(base_addr, FSDMMC_CMD_SETTING_REG_OFFSET, cmd); + FSDMMC_DATA_BARRIER(); + /* 设置参数,同时触发发送命令 */ FSDMMC_WRITE_REG(base_addr, FSDMMC_ARGUMENT_REG_OFFSET, FSDMMC_ARGUMENT_MASK & arg); @@ -154,7 +155,9 @@ FError FSdmmcReset(uintptr base_addr) ret = FSdmmcSoftwareReset(base_addr, FSDMMC_TIMEOUT); if (FSDMMC_SUCCESS != ret) + { return ret; + } /* set card detection */ FSDMMC_WRITE_REG(base_addr, FSDMMC_SD_SEN_REG_OFFSET, 0x0); @@ -207,13 +210,13 @@ FError FSdmmcWaitStatus(uintptr base_addr, int retries) if (FSDMMC_NORMAL_INT_STATUS_EI & status) { - FSDMMC_ERROR("error status: 0x%x, remain retries: %d", status, retries); + FSDMMC_ERROR("Error status: 0x%x, remain retries: %d", status, retries); FSdmmcReset(base_addr); return FSDMMC_ERR_CMD_FAILED; } else if (0 >= retries) { - FSDMMC_ERROR("wait timeout!!! status 0x%x", status); + FSDMMC_ERROR("Wait timeout!!! status 0x%x", status); return FSDMMC_ERR_TIMEOUT; } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.h b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.h index 623f2af31d..82220a99fc 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_hw.h @@ -14,7 +14,7 @@ * FilePath: fsdmmc_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:54:24 - * Description:  This files is for + * Description:  This file contains macros that can be used to access the device. * * Modify History: * Ver   Who        Date         Changes @@ -22,19 +22,26 @@ * 1.0 zhugengyu 2021/12/2 init */ -#ifndef DRIVERS_MMC_FSDMMC_HW_H -#define DRIVERS_MMC_FSDMMC_HW_H +#ifndef FSDMMC_HW_H +#define FSDMMC_HW_H -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "fparameters.h" #include "fio.h" #include "fkernel.h" +#ifdef __aarch64__ +#include "faarch64.h" +#else +#include "fcp15.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /** @name Register Map @@ -288,6 +295,7 @@ extern "C" /**************************** Type Definitions *******************************/ /************************** Variable Definitions *****************************/ +#define FSDMMC_DATA_BARRIER() WMB() /***************** Macros (Inline Functions) Definitions *********************/ diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_intr.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_intr.c index 5fa29e8737..9df432336b 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_intr.c @@ -14,7 +14,8 @@ * FilePath: fsdmmc_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:54:53 - * Description:  This files is for + * Description:  This file contains the functions that are related to interrupt processing + * for the fsdmmc device. * * Modify History: * Ver   Who        Date         Changes @@ -40,11 +41,11 @@ /**************************** Type Definitions *******************************/ /***************** Macros (Inline Functions) Definitions *********************/ -static void FSdmmcCallEvtHandler(FSdmmcEventHandler handler, FSdmmc *instance_p) +static void FSdmmcCallEvtHandler(FSdmmcEventHandler handler, void *arg) { if (NULL != handler) { - handler((void *)instance_p); + handler(arg); } } @@ -70,18 +71,18 @@ u32 FSdmmcGetInterruptMask(uintptr base_addr, u32 intr_type) switch (intr_type) { - case FSDMMC_CMD_INTR: - mask = FSDMMC_READ_REG(base_addr, FSDMMC_NORMAL_INT_EN_REG_OFFSET); - break; - case FSDMMC_ERROR_INTR: - mask = FSDMMC_READ_REG(base_addr, FSDMMC_ERROR_INT_EN_REG_OFFSET); - break; - case FSDMMC_DMA_BD_INTR: - mask = FSDMMC_READ_REG(base_addr, FSDMMC_BD_ISR_EN_REG_OFFSET); - break; - default: - FASSERT(0); - break; + case FSDMMC_CMD_INTR: + mask = FSDMMC_READ_REG(base_addr, FSDMMC_NORMAL_INT_EN_REG_OFFSET); + break; + case FSDMMC_ERROR_INTR: + mask = FSDMMC_READ_REG(base_addr, FSDMMC_ERROR_INT_EN_REG_OFFSET); + break; + case FSDMMC_DMA_BD_INTR: + mask = FSDMMC_READ_REG(base_addr, FSDMMC_BD_ISR_EN_REG_OFFSET); + break; + default: + FASSERT(0); + break; } return mask; @@ -102,24 +103,28 @@ void FSdmmcSetInterruptMask(uintptr base_addr, u32 intr_type, u32 mask, boolean u32 new_mask = 0; if (TRUE == enable) + { new_mask = old_mask | mask; + } else + { new_mask = old_mask & (~mask); + } switch (intr_type) { - case FSDMMC_CMD_INTR: - FSDMMC_WRITE_REG(base_addr, FSDMMC_NORMAL_INT_EN_REG_OFFSET, new_mask); - break; - case FSDMMC_ERROR_INTR: - FSDMMC_WRITE_REG(base_addr, FSDMMC_ERROR_INT_EN_REG_OFFSET, new_mask); - break; - case FSDMMC_DMA_BD_INTR: - FSDMMC_WRITE_REG(base_addr, FSDMMC_BD_ISR_EN_REG_OFFSET, new_mask); - break; - default: - FASSERT(0); - break; + case FSDMMC_CMD_INTR: + FSDMMC_WRITE_REG(base_addr, FSDMMC_NORMAL_INT_EN_REG_OFFSET, new_mask); + break; + case FSDMMC_ERROR_INTR: + FSDMMC_WRITE_REG(base_addr, FSDMMC_ERROR_INT_EN_REG_OFFSET, new_mask); + break; + case FSDMMC_DMA_BD_INTR: + FSDMMC_WRITE_REG(base_addr, FSDMMC_BD_ISR_EN_REG_OFFSET, new_mask); + break; + default: + FASSERT(0); + break; } return; @@ -145,17 +150,20 @@ void FSdmmcCmdInterrupHandler(s32 vector, void *param) if (status & FSDMMC_NORMAL_INT_STATUS_CR) /* 卡移除中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CARD_REMOVED], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CARD_REMOVED], + instance_p->evt_args[FSDMMC_EVT_CARD_REMOVED]); } if (status & FSDMMC_NORMAL_INT_STATUS_CC) /* 命令完成中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_DONE], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_DONE], + instance_p->evt_args[FSDMMC_EVT_CMD_DONE]); } if (status & FSDMMC_NORMAL_INT_STATUS_EI) /* 命令错误中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_ERROR], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_ERROR], + instance_p->evt_args[FSDMMC_EVT_CMD_ERROR]); } FSdmmcClearNormalInterruptStatus(base_addr); @@ -181,12 +189,14 @@ void FSdmmcDmaInterrupHandler(s32 vector, void *param) if (status & FSDMMC_BD_ISR_REG_DAIS) /* DMA 错误中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_ERROR], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_ERROR], + instance_p->evt_args[FSDMMC_EVT_DATA_ERROR]); } if (status & FSDMMC_BD_ISR_REG_RESPE) /* 读 SD 卡操作,AXI BR 通道完成中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_READ_DONE], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_READ_DONE], + instance_p->evt_args[FSDMMC_EVT_DATA_READ_DONE]); } if (status & FSDMMC_BD_ISR_REG_DATFRAX) /* AXI 总线强制释放中断*/ @@ -216,7 +226,8 @@ void FSdmmcDmaInterrupHandler(s32 vector, void *param) if (status & FSDMMC_BD_ISR_REG_TRS) /* DMA 传输完成中断*/ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_WRITE_DONE], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_DATA_WRITE_DONE], + instance_p->evt_args[FSDMMC_EVT_DATA_WRITE_DONE]); } FSdmmcClearBDInterruptStatus(base_addr); @@ -241,7 +252,8 @@ void FSdmmcErrInterrupHandler(s32 vector, void *param) if (status & FSDMMC_ERROR_INT_STATUS_CNR) /* 命令响应错误中断 */ { - FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_RESP_ERROR], instance_p); + FSdmmcCallEvtHandler(instance_p->evt_handler[FSDMMC_EVT_CMD_RESP_ERROR], + instance_p->evt_args[FSDMMC_EVT_CMD_RESP_ERROR]); } if (status & FSDMMC_ERROR_INT_STATUS_CIR) /* 命令索引错误中断 */ @@ -273,10 +285,11 @@ void FSdmmcErrInterrupHandler(s32 vector, void *param) * @note 此函数用于设置FSDMMC中断时注册,被注册的函数被FSdmmcCmdInterrupHandler、FSdmmcErrInterrupHandler * 和FSdmmcDmaInterrupHandler调用 */ -void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler) +void FSdmmcRegisterInterruptHandler(FSdmmc *instance_p, u32 event, FSdmmcEventHandler handler, void *args) { FASSERT(instance_p); instance_p->evt_handler[event] = handler; + instance_p->evt_args[event] = args; } /** @@ -295,7 +308,7 @@ FError FSdmmcInterruptTransfer(FSdmmc *instance_p, FSdmmcCmd *cmd_data_p) if (FALSE == FSdmmcCheckIfCardExists(base_addr)) { - FSDMMC_ERROR("card not found !!! fsdio ctrl base 0x%x", base_addr); + FSDMMC_ERROR("Card not found !!! fsdio ctrl base 0x%x", base_addr); return FSDMMC_ERR_CARD_NO_FOUND; } diff --git a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_sinit.c b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_sinit.c index 96d040abe1..d554fa6cd2 100644 --- a/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/mmc/fsdmmc/fsdmmc_sinit.c @@ -14,8 +14,9 @@ * FilePath: fsdmmc_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:55:09 - * Description:  This files is for - * + * Description:  This file contains the implementation of the fsdmmc driver's static + * initialization functionality. + * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- @@ -41,7 +42,7 @@ /************************** Variable Definitions *****************************/ -extern const FSdmmcConfig FSDMMC_CONFIG_TBL[FSDMMC_HOST_INSTANCE_NUM]; +extern const FSdmmcConfig FSDMMC_CONFIG_TBL[FSDMMC_NUM]; /************************** Function Prototypes ******************************/ /** @@ -56,7 +57,7 @@ const FSdmmcConfig *FSdmmcLookupConfig(u32 instance_id) const FSdmmcConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)FSDMMC_HOST_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FSDMMC_NUM; index++) { if (FSDMMC_CONFIG_TBL[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/nand/Kconfig b/bsp/phytium/libraries/standalone/drivers/nand/Kconfig index 2740b716bf..4638b049f9 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/nand/Kconfig @@ -1,33 +1,33 @@ menu "NAND Configuration" menu "FNAND ip config" - choice - prompt "choice fnand driver" + choice + prompt "choice fnand driver" config ENABLE_FNAND bool prompt "Use FNAND" + + if ENABLE_FNAND + config FNAND_COMMON_DEBUG_EN + bool + prompt "Use FNAND common mode debug" + + config FNAND_DMA_DEBUG_EN + bool + prompt "Use FNAND DMA mode debug" + + config FNAND_TOGGLE_DEBUG_EN + bool + prompt "Use FNAND toggle mode debug" - if ENABLE_FNAND - config FNAND_COMMON_DEBUG_EN - bool - prompt "Use FNAND common mode debug" + config FNAND_ONFI_DEBUG_EN + bool + prompt "Use FNAND onfi mode debug" - config FNAND_DMA_DEBUG_EN - bool - prompt "Use FNAND DMA mode debug" + endif - config FNAND_TOGGLE_DEBUG_EN - bool - prompt "Use FNAND toggle mode debug" - - config FNAND_ONFI_DEBUG_EN - bool - prompt "Use FNAND onfi mode debug" - - endif - - endchoice - endmenu + endchoice + endmenu endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.c index 5396ff2600..1cc2e5067e 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.c @@ -14,11 +14,13 @@ * FilePath: fnand.c * Date: 2022-05-10 14:53:42 * LastEditTime: 2022-05-10 08:56:27 - * Description:  This files is for + * Description:  This file is for functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fnand.h" #include "fnand_hw.h" @@ -130,7 +132,7 @@ FError FNandSendCmd(FNand *instance_p, struct FNandDmaDescriptor *descriptor_p, } else { - FNAND_DEBUG_E("The lack of wait_irq_fun_p"); + FNAND_DEBUG_E("The member wait_irq_fun_p of instance_p is null"); FNAND_WRITEREG(config_p->base_address, FNAND_INTRMASK_OFFSET, FNAND_INTRMASK_ALL_INT_MASK); return FNAND_ERR_IRQ_LACK_OF_CALLBACK; } @@ -145,7 +147,7 @@ FError FNandSendCmd(FNand *instance_p, struct FNandDmaDescriptor *descriptor_p, { if (timeout_cnt++ >= 0xffffff) { - FNAND_DEBUG_E("FNAND_CMD_TYPE is send timeout"); + FNAND_DEBUG_E("FNAND_CMD_TYPE is sending timeout"); return FNAND_OP_TIMEOUT; } } @@ -156,7 +158,7 @@ FError FNandSendCmd(FNand *instance_p, struct FNandDmaDescriptor *descriptor_p, { if (timeout_cnt++ >= 0xffffff) { - FNAND_DEBUG_E("FNAND_CMD_TYPE is send timeout"); + FNAND_DEBUG_E("FNAND_CMD_TYPE is sending timeout"); return FNAND_OP_TIMEOUT; } } @@ -167,7 +169,7 @@ FError FNandSendCmd(FNand *instance_p, struct FNandDmaDescriptor *descriptor_p, { if (timeout_cnt++ >= 0xffffff) { - FNAND_DEBUG_E("FNAND_CMD_TYPE is send timeout"); + FNAND_DEBUG_E("FNAND_CMD_TYPE is sending timeout"); return FNAND_OP_TIMEOUT; } } @@ -178,7 +180,7 @@ FError FNandSendCmd(FNand *instance_p, struct FNandDmaDescriptor *descriptor_p, { if (timeout_cnt++ >= 0xffffff) { - FNAND_DEBUG_E("FNAND_CMD_TYPE is send timeout"); + FNAND_DEBUG_E("FNAND_CMD_TYPE is sending timeout"); return FNAND_OP_TIMEOUT; } } diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.h index 2ded2317a5..12c1012ad2 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.h @@ -14,19 +14,16 @@ * FilePath: fnand.h * Date: 2022-05-07 15:40:42 * LastEditTime: 2022-05-07 15:40:42 - * Description:  This files is for + * Description:  This file is for functions in this file are the minimum required functions + * for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND_H -#define DRIVERS_NAND_FNAND_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FNAND_H +#define FNAND_H #include "ftypes.h" @@ -36,6 +33,13 @@ extern "C" #include "fparameters.h" #include "fkernel.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + #define FNAND_ERR_OPERATION FT_CODE_ERR(ErrModBsp, ErrNand, 0x1u) #define FNAND_ERR_INVAILD_PARAMETER FT_CODE_ERR(ErrModBsp, ErrNand, 0x2u) #define FNAND_IS_BUSY FT_CODE_ERR(ErrModBsp, ErrNand, 0x3u) @@ -52,9 +56,9 @@ extern "C" #define FNAND_MAX_BLOCKS 32768 /* Max number of Blocks */ #define FNAND_MAX_PAGE_SIZE 16384 /* Max page size of NAND \ - flash */ +flash */ #define FNAND_MAX_SPARE_SIZE 1024 /* Max spare bytes of a NAND \ - flash page */ +flash page */ /* dma */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.c index 50bfada9de..655c24270f 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.c @@ -14,11 +14,12 @@ * FilePath: fnand_bbm.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:12 - * Description:  This files is for + * Description:  This file implements the bad block management (BBM) functionality. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -137,35 +138,33 @@ static void FNandConvertBbt(FNand *instance_p, u8 *buf, u32 chip_addr) * Loop through the every 4 blocks in the bitmap */ for (block_index = 0; block_index < FNAND_BBT_ENTRY_NUM_BLOCKS; - block_index++) + block_index++) { block_shift = FNAND_BBTBLOCKSHIFT(block_index); block_type = (data >> block_shift) & FNAND_BLOCK_TYPE_MASK; - // FNAND_BBM_DEBUG_E("block_offset %d,block_shift %d",block_offset,block_shift); - // FNAND_BBM_DEBUG_E("block_type is %d \r\n",block_type); switch (block_type) { - case FNAND_FLASH_BLOCK_FACTORY_BAD: - /* Factory bad block */ - instance_p->bbt_manager[chip_addr].bbt[block_offset] |= - FNAND_BLOCK_FACTORY_BAD << block_shift; - break; - case FNAND_FLASH_BLOCK_RESERVED: - /* Reserved block */ - instance_p->bbt_manager[chip_addr].bbt[block_offset] |= - FNAND_BLOCK_RESERVED << block_shift; - break; - case FNAND_FLASH_BLOCK_BAD: - /* Bad block due to wear */ - instance_p->bbt_manager[chip_addr].bbt[block_offset] |= - FNAND_BLOCK_BAD << block_shift; - break; - default: - /* Good block */ - /* The BBT entry already defaults to - * zero */ - break; + case FNAND_FLASH_BLOCK_FACTORY_BAD: + /* Factory bad block */ + instance_p->bbt_manager[chip_addr].bbt[block_offset] |= + FNAND_BLOCK_FACTORY_BAD << block_shift; + break; + case FNAND_FLASH_BLOCK_RESERVED: + /* Reserved block */ + instance_p->bbt_manager[chip_addr].bbt[block_offset] |= + FNAND_BLOCK_RESERVED << block_shift; + break; + case FNAND_FLASH_BLOCK_BAD: + /* Bad block due to wear */ + instance_p->bbt_manager[chip_addr].bbt[block_offset] |= + FNAND_BLOCK_BAD << block_shift; + break; + default: + /* Good block */ + /* The BBT entry already defaults to + * zero */ + break; } } } @@ -292,12 +291,12 @@ static FError FNandWriteBbt(FNand *instance_p, FNAND_BLOCK_TYPE_MASK; switch (block_type) { - case FNAND_BLOCK_BAD: - case FNAND_BLOCK_FACTORY_BAD: - continue; - default: - /* Good Block */ - break; + case FNAND_BLOCK_BAD: + case FNAND_BLOCK_FACTORY_BAD: + continue; + default: + /* Good Block */ + break; } desc_p->page_offset = block * instance_p->nand_geometry[chip_addr].pages_per_block; @@ -337,7 +336,7 @@ static FError FNandWriteBbt(FNand *instance_p, * Calculate the bit mask for 4 blocks at a time in loop */ for (block_index = 0; block_index < FNAND_BBT_ENTRY_NUM_BLOCKS; - block_index++) + block_index++) { block_shift = FNAND_BBTBLOCKSHIFT(block_index); buf[block_offset] &= ~(mask[Data & @@ -345,15 +344,13 @@ static FError FNandWriteBbt(FNand *instance_p, << block_shift); Data >>= FNAND_BBT_BLOCK_SHIFT; } - // FNAND_BBM_DEBUG_I("buf[%d] 0x%x",block_offset,buf[block_offset]); + } /* * Write the Bad Block Table(BBT) to flash */ - // printf("erase_p is %p \r\n",instance_p->erase_p); ret = FNandEraseBlock(instance_p, block, chip_addr); - //instance_p->erase_p(instance_p, block, chip_addr); if (ret != FT_SUCCESS) { return ret; @@ -412,8 +409,8 @@ static void FNandCreateBbt(FNand *instance_p, u32 chip_addr) * Scan all the blocks for factory marked bad blocks */ for (block_index = 0; block_index < - instance_p->nand_geometry[chip_addr].num_blocks; - block_index++) + instance_p->nand_geometry[chip_addr].num_blocks; + block_index++) { /* * Block offset in Bad Block Table(BBT) entry @@ -445,11 +442,11 @@ static void FNandCreateBbt(FNand *instance_p, u32 chip_addr) * pattern */ for (length = 0; length < - instance_p->bbt_manager[chip_addr].bb_pattern.length; - length++) + instance_p->bbt_manager[chip_addr].bb_pattern.length; + length++) { if (buf[instance_p->bbt_manager[chip_addr].bb_pattern.offset + length] != - instance_p->bbt_manager[chip_addr].bb_pattern.pattern[length]) + instance_p->bbt_manager[chip_addr].bb_pattern.pattern[length]) { /* Bad block found */ instance_p->bbt_manager[chip_addr].bbt[block_offset] |= @@ -480,14 +477,14 @@ FError FNandSearchBbt(FNand *instance_p, FNandBbtDesc *desc, u32 chip_addr) ver_offset = desc->ver_offset; max_blocks = desc->max_blocks; sig_length = desc->sig_length; - FNAND_BBM_DEBUG_I("FNandSearchBbt is start 0x%x", start_block); - FNAND_BBM_DEBUG_I("pages_per_block is start %d", instance_p->nand_geometry[chip_addr].pages_per_block); + FNAND_BBM_DEBUG_I("FNandSearchBbt starts at 0x%x", start_block); + FNAND_BBM_DEBUG_I("Pages_per_block starts at %d", instance_p->nand_geometry[chip_addr].pages_per_block); for (block = 0; block < max_blocks; block++) { pageoff = (start_block - block) * instance_p->nand_geometry[chip_addr].pages_per_block; - FNAND_BBM_DEBUG_I("block 0x%x", block); - FNAND_BBM_DEBUG_I("%s, pageoff is 0x%x", __func__, pageoff); + FNAND_BBM_DEBUG_I("Block 0x%x", block); + FNAND_BBM_DEBUG_I("%s, Pageoff is 0x%x", __func__, pageoff); ret = FNandReadPageOOb(instance_p, pageoff, buf, 0, sizeof(buf), chip_addr); if (ret != FT_SUCCESS) { @@ -565,11 +562,11 @@ FError FNandReadBbt(FNand *instance_p, u32 chip_addr) /* * Valid BBT & Mirror BBT found */ - FNAND_BBM_DEBUG_I("desc_p->version > mirror_desc_p->version read page is %d", desc_p->page_offset); + FNAND_BBM_DEBUG_I("The desc_p->version > mirror_desc_p->version is not null , the page_offset is %d", desc_p->page_offset); ret = FNandReadPage(instance_p, desc_p->page_offset, buf, 0, bbtlen, NULL, 0, 0, chip_addr); if (ret != FT_SUCCESS) { - FNAND_BBM_DEBUG_I("desc_p->version > mirror_desc_p->version read page is error 0x%x", ret); + FNAND_BBM_DEBUG_I("The desc_p->version > mirror_desc_p->version is not null , the FNandReadPage is error 0x%x", ret); return ret; } /* @@ -590,11 +587,11 @@ FError FNandReadBbt(FNand *instance_p, u32 chip_addr) } else if (desc_p->version < mirror_desc_p->version) { - FNAND_BBM_DEBUG_I("desc_p->version < mirror_desc_p->version read page is %d", mirror_desc_p->page_offset); + FNAND_BBM_DEBUG_I("desc_p->version < mirror_desc_p->version is not null, the page_offset is %d", mirror_desc_p->page_offset); ret = FNandReadPage(instance_p, mirror_desc_p->page_offset, buf, 0, bbtlen, NULL, 0, 0, chip_addr); if (ret != FT_SUCCESS) { - FNAND_BBM_DEBUG_I("desc_p->version < mirror_desc_p->version read page is error 0x%x", ret); + FNAND_BBM_DEBUG_I("desc_p->version < mirror_desc_p->version is not null, the FNandReadPage is error 0x%x", ret); return ret; } /* @@ -616,12 +613,12 @@ FError FNandReadBbt(FNand *instance_p, u32 chip_addr) else { /* Both are up-to-date */ - FNAND_BBM_DEBUG_I("Both are up-to-date read page is %d", desc_p->page_offset); + FNAND_BBM_DEBUG_I("Both are up-to-date, the page_offset is %d", desc_p->page_offset); ret = FNandReadPage(instance_p, desc_p->page_offset, buf, 0, bbtlen, NULL, 0, 0, chip_addr); if (ret != FT_SUCCESS) { - FNAND_BBM_DEBUG_I("Both are up-to-date read page is error 0x%x", ret); + FNAND_BBM_DEBUG_I("Both are up-to-date, the FNandReadPage is error 0x%x", ret); return ret; } @@ -702,7 +699,7 @@ FError FNandReadBbt(FNand *instance_p, u32 chip_addr) static void FNandBbtDumpDebug(FNand *instance_p) { int i; - FNAND_BBM_DEBUG_W("/********************* master bbt descriptor **********************/"); + FNAND_BBM_DEBUG_W("/********************* Master bbt descriptor **********************/"); FNAND_BBM_DEBUG_I("page_offset 0x%x", instance_p->bbt_manager[0].bbt_desc.page_offset); /* Page offset where BBT resides */ FNAND_BBM_DEBUG_I("sig_offset 0x%x", instance_p->bbt_manager[0].bbt_desc.sig_offset); /* Signature offset in Spare area */ @@ -711,12 +708,12 @@ static void FNandBbtDumpDebug(FNand *instance_p) FNAND_BBM_DEBUG_I("max_blocks 0x%x", instance_p->bbt_manager[0].bbt_desc.max_blocks); /* Max blocks to search for BBT */ for (i = 0; i < 4; i++) { - FNAND_BBM_DEBUG_I("signature[%d] %c", i, instance_p->bbt_manager[0].bbt_desc.signature[i]); + FNAND_BBM_DEBUG_I("Signature[%d] %c", i, instance_p->bbt_manager[0].bbt_desc.signature[i]); } FNAND_BBM_DEBUG_I("version 0x%x", instance_p->bbt_manager[0].bbt_desc.version); /* BBT version */ FNAND_BBM_DEBUG_I("valid 0x%x", instance_p->bbt_manager[0].bbt_desc.valid); /* BBT descriptor is valid or not */ - FNAND_BBM_DEBUG_W("/********************* mirror bbt descriptor **********************/"); + FNAND_BBM_DEBUG_W("/********************* Mirror bbt descriptor **********************/"); FNAND_BBM_DEBUG_I("page_offset 0x%x", instance_p->bbt_manager[0].bbt_mirror_desc.page_offset); /* Page offset where BBT resides */ FNAND_BBM_DEBUG_I("sig_offset 0x%x", instance_p->bbt_manager[0].bbt_mirror_desc.sig_offset); /* Signature offset in Spare area */ FNAND_BBM_DEBUG_I("ver_offset 0x%x", instance_p->bbt_manager[0].bbt_mirror_desc.ver_offset); /* Offset of BBT version */ @@ -730,7 +727,7 @@ static void FNandBbtDumpDebug(FNand *instance_p) FNAND_BBM_DEBUG_I("valid 0x%x", instance_p->bbt_manager[0].bbt_mirror_desc.valid); /* BBT descriptor is valid or not */ - FNAND_BBM_DEBUG_W("/********************* bbt info **********************/"); + FNAND_BBM_DEBUG_W("/********************* Bbt info **********************/"); FtDumpHexWord((const u32 *)instance_p->bbt_manager[0].bbt, instance_p->nand_geometry[0].num_blocks >> FNAND_BBT_BLOCK_SHIFT); } @@ -791,7 +788,7 @@ FError FNandScanBbt(FNand *instance_p, u32 chip_addr) } else { - FNAND_BBM_DEBUG_I("old bbt is valid"); + FNAND_BBM_DEBUG_I("Old bbt is valid"); FNandBbtDumpDebug(instance_p) ; } @@ -825,9 +822,13 @@ FError FNandIsBlockBad(FNand *instance_p, u32 block, u32 chip_addr) BlockType = (data >> block_shift) & FNAND_BLOCK_TYPE_MASK; if (BlockType != FNAND_BLOCK_GOOD) + { return FT_SUCCESS; + } else + { return FNAND_VALUE_FAILURE; + } } diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.h index 4159553147..aa525c8d59 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_bbm.h @@ -14,25 +14,27 @@ * FilePath: fnand_bbm.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:17 - * Description:  This files is for + * Description:  This file implements the Bad Block Management (BBM) functionality. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND_BBM_H -#define DRIVERS_NAND_FNAND_BBM_H +#ifndef FNAND_BBM_H +#define FNAND_BBM_H + +#include "ftypes.h" +#include "fnand.h" + #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fnand.h" - /************************** Constant Definitions *****************************/ /* * Block definitions for RAM based Bad Block Table (BBT) @@ -54,38 +56,38 @@ extern "C" second page \ for bad block \ information \ - */ +*/ #define FNAND_BBT_DESC_PAGE_OFFSET 0 /* Page offset of Bad \ - Block Table Desc */ +Block Table Desc */ #define FNAND_BBT_DESC_SIG_OFFSET 8 /* Bad Block Table \ - signature offset */ +signature offset */ #define FNAND_BBT_DESC_VER_OFFSET 12 /* Bad block Table \ - version offset */ +version offset */ #define FNAND_BBT_DESC_SIG_LEN 4 /* Bad block Table \ - signature length */ +signature length */ #define FNAND_BBT_DESC_MAX_BLOCKS 4 /* Bad block Table \ - max blocks */ +max blocks */ #define FNAND_BBT_BLOCK_SHIFT 2 /* Block shift value \ - for a block in BBT */ +for a block in BBT */ #define FNAND_BBT_ENTRY_NUM_BLOCKS 4 /* Num of blocks in \ - one BBT entry */ +one BBT entry */ #define FNAND_BB_PATTERN_OFFSET_SMALL_PAGE 5 /* Bad block pattern \ - offset in a page */ +offset in a page */ #define FNAND_BB_PATTERN_LENGTH_SMALL_PAGE 1 /* Bad block pattern \ - length */ +length */ #define FNAND_BB_PATTERN_OFFSET_LARGE_PAGE 0 /* Bad block pattern \ offset in a large \ - page */ +page */ #define FNAND_BB_PATTERN_LENGTH_LARGE_PAGE 2 /* Bad block pattern \ - length */ +length */ #define FNAND_BB_PATTERN 0xFF /* Bad block pattern \ to search in a page \ - */ +*/ #define FNAND_BLOCK_TYPE_MASK 0x03 /* Block type mask */ #define FNAND_BLOCK_SHIFT_MASK 0x06 /* Block shift mask \ for a Bad Block Table \ - entry byte */ +entry byte */ /**************************** Type Definitions *******************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.c index 00627cc2f9..6cd6ad9e54 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.c @@ -14,11 +14,12 @@ * FilePath: fnand_common_cmd.c * Date: 2022-06-24 03:51:06 * LastEditTime: 2022-06-24 03:51:07 - * Description: This file is for + * Description: This file is for nand generic command documentation * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fnand_common_cmd.h" @@ -79,9 +80,9 @@ * loss). */ #define __DIVIDE(dividend, divisor) ({ \ - (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ - DIV_ROUND_UP(dividend, divisor) : \ - DIV_ROUND_UP_ULL(dividend, divisor)); \ + (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ + DIV_ROUND_UP(dividend, divisor) : \ + DIV_ROUND_UP_ULL(dividend, divisor)); \ }) #define PSEC_TO_NSEC(x) __DIVIDE(x, 1000) #define PSEC_TO_MSEC(x) __DIVIDE(x, 1000000000) @@ -184,7 +185,7 @@ static FError FNandFlashReadStatus(FNand *instance_p, u32 chip_addr) return ret; } - FNAND_COMMON_DEBUG_I("read status is 0x%x", instance_p->dma_data_buffer.data_buffer[0]); + FNAND_COMMON_DEBUG_I("Read status is 0x%x", instance_p->dma_data_buffer.data_buffer[0]); return (instance_p->dma_data_buffer.data_buffer[0] == 0xe0) ? FT_SUCCESS : FNAND_IS_BUSY; } @@ -379,7 +380,6 @@ static FError FNandPageWriteHwEcc(FNand *instance_p, u32 page_addr, u8 *buf, u32 { nand_state = FNAND_READREG(instance_p->config.base_address, FNAND_STATE_OFFSET); } - // printf("write after nand_state 0x%x \r\n",nand_state); while (FNandFlashReadStatus(instance_p, chip_addr) == FNAND_IS_BUSY) ; /* wait i/o idle */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.h index 2c2733d5bd..0b0b95c258 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_common_cmd.h @@ -14,11 +14,12 @@ * FilePath: fnand_common_cmd.h * @Date: 2022-07-05 19:01:01 * @LastEditTime: 2022-07-05 19:01:02 - * @Description: This file is for + * @Description: This file is for nand generic command documentation * * @Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #ifndef DRIVERS_NAND_COMMON_CMD_H @@ -27,6 +28,10 @@ #include "ftypes.h" #include "fnand.h" +#ifdef __cplusplus +extern "C" +{ +#endif /* * Mandatory commands */ @@ -36,31 +41,31 @@ #define NAND_CMD_CHANGE_READ_COLUMN1 0x05 /* NAND Random data Read \ Column command (1st \ - cycle) */ +cycle) */ #define NAND_CMD_CHANGE_READ_COLUMN2 0xE0 /* NAND Random data Read \ Column command (2nd \ - cycle) */ +cycle) */ #define NAND_CMD_BLOCK_ERASE1 0x60 /* NAND Block Erase \ - (1st cycle) */ +(1st cycle) */ #define NAND_CMD_BLOCK_ERASE2 0xD0 /* NAND Block Erase \ - (2nd cycle) */ +(2nd cycle) */ #define NAND_CMD_PAGE_PROG1 0x80 /* NAND Page Program \ command (1st cycle) \ - */ +*/ #define NAND_CMD_PAGE_PROG2 0x10 /* NAND Page Program \ command (2nd cycle) \ - */ +*/ #define NAND_CMD_CHANGE_WRITE_COLUMN 0x85 /* NAND Change Write \ - Column command */ +Column command */ #define NAND_CMD_READ_ID 0x90 /* NAND Read ID \ - command */ +command */ #define NAND_CMD_READ_PARAM_PAGE 0xEC /* NAND Read \ Parameter Page \ - command */ +command */ #define NAND_CMD_RESET 0xFF /* NAND Reset \ - command */ +command */ #define NAND_END_CMD_NONE 0xfff /* No End command */ @@ -70,5 +75,9 @@ FError FNandFlashReset(FNand *instance_p, u32 chip_addr) ; FError FNandFlashReadId(FNand *instance_p, u8 address, u8 *id_buffer, u32 buffer_length, u32 chip_addr); void FNandFlashFuncRegister(FNand *instance_p); +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.c index 0c76bce917..2395ceefdc 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.c @@ -14,11 +14,12 @@ * FilePath: fnand_dma.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:22 - * Description:  This files is for + * Description:  This file is dma descriptor management API. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -46,12 +47,12 @@ void FNandDmaDump(struct FNandDmaDescriptor *descriptor_p) { - FNAND_DMA_DEBUG_I("Phytium NFC cmd dump:\n"); - FNAND_DMA_DEBUG_I("cmd0:%x, cmd1:%x, ctrl:%x, page_cnt:%d\n", + FNAND_DMA_DEBUG_I("Phytium NFC cmd dump: "); + FNAND_DMA_DEBUG_I("cmd0:%x, cmd1:%x, ctrl:%x, page_cnt:%d ", descriptor_p->cmd0, descriptor_p->cmd1, descriptor_p->cmd_ctrl.ctrl, descriptor_p->page_cnt); - FNAND_DMA_DEBUG_I("mem_addr_first:%02x %02x %02x %02x %02x\n", + FNAND_DMA_DEBUG_I("mem_addr_first:%02x %02x %02x %02x %02x ", descriptor_p->mem_addr_first[0], descriptor_p->mem_addr_first[1], descriptor_p->mem_addr_first[2], descriptor_p->mem_addr_first[3], descriptor_p->mem_addr_first[4]); - FNAND_DMA_DEBUG_I("addr:%02x %02x %02x %02x %02x\n", + FNAND_DMA_DEBUG_I("addr:%02x %02x %02x %02x %02x ", descriptor_p->addr[0], descriptor_p->addr[1], descriptor_p->addr[2], descriptor_p->addr[3], descriptor_p->addr[4]); FNAND_DMA_DEBUG_I(" csel : 0x%x ", descriptor_p->cmd_ctrl.nfc_ctrl.csel); @@ -72,7 +73,7 @@ static void FNandAddrCorrect(struct FNandDmaDescriptor *descriptor_p, int i, j; if (addr_length == 0 || addr_p == NULL) { - FNAND_DMA_DEBUG_I("addr_p is null ,Calibration is not required "); + FNAND_DMA_DEBUG_I("The addr_p is null , Calibration is not required "); return; } @@ -100,7 +101,6 @@ FError FNandDmaPack(FNandCmdFormat *cmd_format, u32 i; FASSERT(cmd_format != NULL); FASSERT(descriptor_p != NULL); - // printf(" descriptor_p is %p \r\n",descriptor_p); descriptor_p->cmd_ctrl.ctrl = 0; /* cmd */ @@ -119,7 +119,7 @@ FError FNandDmaPack(FNandCmdFormat *cmd_format, /* addr */ FNandAddrCorrect(descriptor_p, pack_data_p->addr_p, pack_data_p->addr_length); descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type = cmd_format->cmd_type; /* cmd type */ - FNAND_DMA_DEBUG_I("cmd_type is %x \r\n", descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type); + FNAND_DMA_DEBUG_I("cmd_type is %x", descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type); if (pack_data_p->contiune_dma) { descriptor_p->cmd_ctrl.nfc_ctrl.nc = 1; @@ -138,10 +138,14 @@ FError FNandDmaPack(FNandCmdFormat *cmd_format, } if (cmd_format->auto_rs) + { descriptor_p->cmd_ctrl.nfc_ctrl.auto_rs = 1; + } if (cmd_format->ecc_en) + { descriptor_p->cmd_ctrl.nfc_ctrl.ecc_en = 1; + } /* invalid descriptor and buffer */ FCacheDCacheInvalidateRange((intptr)descriptor_p, sizeof(struct FNandDmaDescriptor)); diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.h index 4e792eaa4d..65a75826cb 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_dma.h @@ -14,23 +14,25 @@ * FilePath: fnand_dma.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:27 - * Description:  This files is for + * Description:  This file is dma descriptor management API. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND_DMA_H -#define DRIVERS_NAND_FNAND_DMA_H +#ifndef FNAND_DMA_H +#define FNAND_DMA_H + +#include "ftypes.h" + #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" - #define FNAND_CMDCTRL_TYPE_RESET 0x00 /* reset */ #define FNAND_CMDCTRL_TYPE_SET_FTR 0x01 /* Set features */ #define FNAND_CMDCTRL_TYPE_GET_FTR 0x02 /* Get features */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.c index f76f28544c..e547eed19d 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.c @@ -14,11 +14,12 @@ * FilePath: fnand_ecc.c * Date: 2022-05-12 14:17:42 * LastEditTime: 2022-05-12 15:56:27 - * Description:  This files is for + * Description:  This file is for ecc validation related api * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -45,59 +46,99 @@ u32 FNandGetEccTotalLength(u32 bytes_per_page, u32 ecc_strength) int ecc_total = 0; switch (bytes_per_page) { - case 0x200: - if (ecc_strength == 8) - ecc_total = 0x0D; - else if (ecc_strength == 4) - ecc_total = 7; - else if (ecc_strength == 2) - ecc_total = 4; - else + case 0x200: + if (ecc_strength == 8) + { + ecc_total = 0x0D; + } + else if (ecc_strength == 4) + { + ecc_total = 7; + } + else if (ecc_strength == 2) + { + ecc_total = 4; + } + else + { + ecc_total = 0; + } + break; + case 0x800: + if (ecc_strength == 8) + { + ecc_total = 0x34; + } + else if (ecc_strength == 4) + { + ecc_total = 0x1a; + } + else if (ecc_strength == 2) + { + ecc_total = 0xd; + } + else + { + ecc_total = 0; + } + break; + case 0x1000: + if (ecc_strength == 8) + { + ecc_total = 0x68; + } + else if (ecc_strength == 4) + { + ecc_total = 0x34; + } + else if (ecc_strength == 2) + { + ecc_total = 0x1a; + } + else + { + ecc_total = 0; + } + break; + case 0x2000: + if (ecc_strength == 8) + { + ecc_total = 0xD0; + } + else if (ecc_strength == 4) + { + ecc_total = 0x68; + } + else if (ecc_strength == 2) + { + ecc_total = 0x34; + } + else + { + ecc_total = 0; + } + break; + case 0x4000: + if (ecc_strength == 8) + { + ecc_total = 0x1A0; + } + if (ecc_strength == 4) + { + ecc_total = 0xD0; + } + else if (ecc_strength == 2) + { + ecc_total = 0x68; + } + else + { + ecc_total = 0; + } + break; + default: ecc_total = 0; - break; - case 0x800: - if (ecc_strength == 8) - ecc_total = 0x34; - else if (ecc_strength == 4) - ecc_total = 0x1a; - else if (ecc_strength == 2) - ecc_total = 0xd; - else - ecc_total = 0; - break; - case 0x1000: - if (ecc_strength == 8) - ecc_total = 0x68; - else if (ecc_strength == 4) - ecc_total = 0x34; - else if (ecc_strength == 2) - ecc_total = 0x1a; - else - ecc_total = 0; - break; - case 0x2000: - if (ecc_strength == 8) - ecc_total = 0xD0; - else if (ecc_strength == 4) - ecc_total = 0x68; - else if (ecc_strength == 2) - ecc_total = 0x34; - else - ecc_total = 0; - break; - case 0x4000: - if (ecc_strength == 8) - ecc_total = 0x1A0; - if (ecc_strength == 4) - ecc_total = 0xD0; - else if (ecc_strength == 2) - ecc_total = 0x68; - else - ecc_total = 0; - break; - default: - ecc_total = 0; - break; + break; } FNAND_ECC_DEBUG_I("[%s %d]writesize: 0x%x, ecc strength: %d, ecc_total: 0x%x\n", __func__, __LINE__, bytes_per_page, ecc_strength, ecc_total); @@ -202,7 +243,7 @@ s32 FNandCorrectEcc(uintptr_t base_address, u32 ecc_step_size, u32 hw_ecc_steps, int stat = 0; if (!buf) { - FNAND_ECC_DEBUG_E("page buffer is null"); + FNAND_ECC_DEBUG_E("Page buffer is null"); return -1; } @@ -210,18 +251,9 @@ s32 FNandCorrectEcc(uintptr_t base_address, u32 ecc_step_size, u32 hw_ecc_steps, for (i = 0; i < hw_ecc_steps; i++) { for (j = 0; j < 4; j++) - { - // value = FNAND_READREG(base_address, 0xB8 + 4 * (2 * i + j)); + { value = FNAND_READREG(base_address, 0xB8 + 0x10 * i + 4 * j); - // FNAND_ECC_DEBUG_W("index:%x i is %d ,j is %d ", - // 0xB8 + 0x10 * i + 4*j,i,j); - if (value) - { - // FNAND_ECC_DEBUG_W("offset:%x value:0x%08x\n", - // 0xB8 + 0x10 * i + 4*j, value); - //phytium_nfc_data_dump2(nfc, nfc->dma_buf + (ecc_step_size * i + tmp/8)/512, 512); - } - + tmp = value & 0xFFFF; if (tmp && (tmp <= 4096)) { diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.h index 3c0bbe5bd9..9c98ae7502 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_ecc.h @@ -14,24 +14,30 @@ * FilePath: fnand_ecc.h * Date: 2022-05-12 11:17:42 * LastEditTime: 2022-05-12 13:56:27 - * Description:  This files is for + * Description:  This file is for ecc validation related api * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND_ECC_H -#define DRIVERS_NAND_FNAND_ECC_H +#ifndef FNAND_ECC_H +#define FNAND_ECC_H #include "ftypes.h" #include "fnand_hw.h" #include "stdio.h" +#ifdef __cplusplus +extern "C" +{ +#endif + static inline void FNandEnableHwEcc(uintptr_t base_address) { FNAND_SETBIT(base_address, FNAND_CTRL0_OFFSET, FNAND_CTRL0_ECC_EN_MASK); - // printf("base_address is %p ,value is 0x%x \r\n",base_address,FNAND_READREG(base_address,FNAND_CTRL0_OFFSET)); + } @@ -42,4 +48,9 @@ static inline void FNandDisableHwEcc(uintptr_t base_address) u32 FNandGetEccTotalLength(u32 bytes_per_page, u32 ecc_strength); s32 FNandCorrectEcc(uintptr_t base_address, u32 ecc_step_size, u32 hw_ecc_steps, u8 *buf, u32 length); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_g.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_g.c index 4686dbe832..294c63cd38 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_g.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_g.c @@ -14,11 +14,12 @@ * FilePath: fnand_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:31 - * Description:  This files is for + * Description:  This file is for configuration table for devices * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fnand.h" @@ -31,7 +32,7 @@ FNandConfig FNandConfigTable[FNAND_NUM] = { .instance_id = FNAND_INSTANCE0, /* Id of device*/ .irq_num = FNAND_IRQ_NUM, /* Irq number */ - .base_address = FNAND_BASEADDRESS, + .base_address = FNAND_BASE_ADDR, .ecc_strength = 8, /* 每次ecc 步骤纠正的位数 */ .ecc_step_size = 512 /* 进行读写操作时,单次ecc 的步骤的跨度 */ }, diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.c index e72a98a260..9b6cafc8a2 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.c @@ -14,11 +14,12 @@ * FilePath: fnand_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:36 - * Description:  This files is for + * Description:  This file contains macros that can be used to access the device. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fnand_hw.h" diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.h index cf71a2d04c..d49df564dc 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_hw.h @@ -14,26 +14,30 @@ * FilePath: fnand_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:40 - * Description:  This files is for + * Description:  This file contains macros that can be used to access the device. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND_HW_H -#define DRIVERS_NAND_FNAND_HW_H +#ifndef FNAND_HW_H +#define FNAND_HW_H + + +#include "fkernel.h" +#include "ftypes.h" +#include "fio.h" +#include "fkernel.h" + #ifdef __cplusplus extern "C" { #endif -#include "fkernel.h" -#include "ftypes.h" -#include "fio.h" -#include "fkernel.h" #define FNAND_CTRL0_OFFSET 0x00000000U #define FNAND_CTRL1_OFFSET 0x00000004U diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.c index 4b6c90713f..51abd5100c 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.c @@ -14,11 +14,13 @@ * FilePath: fnand_id.c * Date: 2022-07-06 08:34:27 * LastEditTime: 2022-07-06 08:34:27 - * Description: This file is for + * Description: This file is for functions in this file are the read id required functions + * for this driver. * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fdebug.h" #include "fnand.h" @@ -78,7 +80,9 @@ static int FnandIdHasPeriod(u8 *id_data_p, int arrlen, int period) for (i = 0; i < period; i++) for (j = i + period; j < arrlen; j += period) if (id_data_p[i] != id_data_p[j]) + { return 0; + } return 1; } @@ -88,24 +92,34 @@ static int FNandIdLen(u8 *id_data_p, int data_length) for (last_nonzero = data_length - 1; last_nonzero >= 0; last_nonzero--) if (id_data_p[last_nonzero]) + { break; + } /* All zeros */ if (last_nonzero < 0) + { return 0; + } /* Calculate wraparound period */ for (period = 1; period < data_length; period++) if (FnandIdHasPeriod(id_data_p, data_length, period)) + { break; + } /* There's a repeated pattern */ if (period < data_length) + { return period; + } /* There are trailing zeros */ if (last_nonzero < data_length - 1) + { return last_nonzero + 1; + } /* No pattern detected */ return data_length; @@ -167,7 +181,7 @@ static FError FNandIdDetect(FNand *instance_p, u32 chip_addr) /* step 5 compare ID string and device id */ if (id_data[0] != maf_id || id_data[1] != dev_id) { - FNAND_ID_DEBUG_E("second ID read did not match %02x,%02x against %02x,%02x\n", + FNAND_ID_DEBUG_E("Second ID read did not match %02x,%02x against %02x,%02x\n", maf_id, dev_id, id_data[0], id_data[1]); return FNAND_ERR_NOT_MATCH; } @@ -183,15 +197,15 @@ static FError FNandIdDetect(FNand *instance_p, u32 chip_addr) return FNAND_ERR_NOT_MATCH; } - FNAND_ID_DEBUG_I("find manufacturer"); + FNAND_ID_DEBUG_I("Find manufacturer"); if (manufacturer_p->ops->detect) { - FNAND_ID_DEBUG_I("manufacturer_p->ops->detect"); + FNAND_ID_DEBUG_I("manufacturer_p->ops->detect function work"); return manufacturer_p->ops->detect(instance_p, &nand_id, chip_addr); } else { - FNAND_ID_DEBUG_E("manufacturer detect is empty"); + FNAND_ID_DEBUG_E("Manufacturer detect is empty"); return FNAND_ERR_NOT_MATCH; } @@ -208,7 +222,7 @@ FError FNandDetect(FNand *instance_p) ret = FNandIdDetect(instance_p, i); if (ret != FT_SUCCESS) { - FNAND_ID_DEBUG_W("normal flash is not found"); + FNAND_ID_DEBUG_W("Normal flash is not found"); } else { @@ -221,7 +235,7 @@ FError FNandDetect(FNand *instance_p) ret = FNandToggleInit(instance_p, i); /* toggle 1.0 */ if (ret != FT_SUCCESS) { - FNAND_ID_DEBUG_W("toggle flash is not found"); + FNAND_ID_DEBUG_W("Toggle flash is not found"); } else { diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.h index ccc80290c2..23a5d0551b 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_id.h @@ -14,22 +14,28 @@ * FilePath: fnand_id.h * Date: 2022-07-06 14:19:15 * LastEditTime: 2022-07-06 14:19:15 - * Description: This file is for + * Description: This file is for functions in this file are the read id required functions + * for this driver. * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_DRIVER_FNAND -#define DRIVERS_NAND_DRIVER_FNAND +#ifndef FNAND_ID_H +#define FNAND_ID_H #include "ftypes.h" #include "fnand.h" +#ifdef __cplusplus +extern "C" +{ +#endif struct FNandManuFacturerOps @@ -49,5 +55,8 @@ typedef struct FError FNandDetect(FNand *instance_p); +#ifdef __cplusplus +} +#endif #endif diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_intr.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_intr.c index b4bdb48ea8..6150cb9c92 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_intr.c @@ -14,11 +14,12 @@ * FilePath: fnand_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:46 - * Description:  This files is for + * Description:  This file contains functions related to fnand interrupt handling. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_option.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_option.c index 285e17e946..c10349aa9d 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_option.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_option.c @@ -14,11 +14,12 @@ * FilePath: fnand_option.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:51 - * Description:  This files is for + * Description:  This file is for options functions for the fnand component. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -44,13 +45,13 @@ FError FNandSetOption(FNand *instance_p, u32 options, u32 value) switch (options) { - case FNAND_OPS_INTER_MODE_SELECT: - FASSERT(FNAND_TOG_ASYN_DDR >= value) ; - FNAND_CLEARBIT(config_p->base_address, FNAND_CTRL0_OFFSET, FNAND_CTRL0_INTER_MODE(3UL)) ; - FNAND_SETBIT(config_p->base_address, FNAND_CTRL0_OFFSET, FNAND_CTRL0_INTER_MODE((unsigned long)value)) ; - break; - default: - return FNAND_ERR_INVAILD_PARAMETER; + case FNAND_OPS_INTER_MODE_SELECT: + FASSERT(FNAND_TOG_ASYN_DDR >= value) ; + FNAND_CLEARBIT(config_p->base_address, FNAND_CTRL0_OFFSET, FNAND_CTRL0_INTER_MODE(3UL)) ; + FNAND_SETBIT(config_p->base_address, FNAND_CTRL0_OFFSET, FNAND_CTRL0_INTER_MODE((unsigned long)value)) ; + break; + default: + return FNAND_ERR_INVAILD_PARAMETER; } return FT_SUCCESS; diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_sinit.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_sinit.c index f6e714ece0..c49a91cf83 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_sinit.c @@ -14,11 +14,13 @@ * FilePath: fnand_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:56:56 - * Description:  This files is for + * Description:  This file contains the implementation of the fnand driver's static + * initialization functionality. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.c index d8c364485a..62f86ed34e 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.c @@ -14,11 +14,12 @@ * FilePath: fnand_timing.c * Date: 2022-05-09 14:53:42 * LastEditTime: 2022-05-09 08:56:27 - * Description:  This files is for + * Description:   This file is for timings configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "ferror_code.h" #include "fnand.h" @@ -339,92 +340,92 @@ FError FNandTimingInterfaceUpdate(FNand *instance_p, u32 chip_addr) FNAND_CLEARBIT(config_p->base_address, FNAND_CTRL1_OFFSET, FNAND_CTRL1_SAMPL_PHASE_MAKE(0xffffUL)); /* clear sampl_phase */ switch (instance_p->inter_mode[chip_addr]) { - case FNAND_ASYN_SDR: - if (FNAND_TIMING_MODE4 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - target_timming_data = fnand_timing_asy_mode4; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(4UL) ; - } - else if (FNAND_TIMING_MODE3 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - target_timming_data = fnand_timing_asy_mode3; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; - } - else if (FNAND_TIMING_MODE2 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - target_timming_data = fnand_timing_asy_mode2; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(6UL) ; - } - else if (FNAND_TIMING_MODE1 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - target_timming_data = fnand_timing_asy_mode1; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; - } - else - { - target_timming_data = fnand_timing_asy_mode0; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(1UL) ; - } - ret = FNandMemcpyToReg16(instance_p, FNAND_ASY_TIMING0_OFFSET, 4, target_timming_data, FNAND_TIMING_ASY_NUM); - if (ret != FT_SUCCESS) - { - return ret; - } - FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 1); - break; - case FNAND_ONFI_DDR: - if (FNAND_TIMING_MODE4 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x30); - target_timming_data = fnand_timing_syn_mode4; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0xdUL) ; - } - else if (FNAND_TIMING_MODE3 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x18); - target_timming_data = fnand_timing_syn_mode3; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; - } - else if (FNAND_TIMING_MODE2 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x20); - target_timming_data = fnand_timing_syn_mode2; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x8UL) ; - } - else if (FNAND_TIMING_MODE1 == (instance_p->timing_mode[chip_addr] & 0xf)) - { - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x40); - target_timming_data = fnand_timing_syn_mode1; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x12UL) ; - } - else - { - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x40); - target_timming_data = fnand_timing_syn_mode0; - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x12UL) ; - } - ret = FNandMemcpyToReg16(instance_p, FNAND_SYN_TIMING6_OFFSET, 4, target_timming_data, FNAND_TIMING_SYN_NUM); - if (ret != FT_SUCCESS) - { - return ret; - } - FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); - break; - case FNAND_TOG_ASYN_DDR: - value = FNAND_CTRL1_SAMPL_PHASE_MAKE(8UL); - target_timming_data = fnand_timing_tog_ddr_mode0; - ret = FNandMemcpyToReg16(instance_p, FNAND_TOG_TIMING13_OFFSET, 4, target_timming_data, FNAND_TIMING_SYN_NUM); - if (ret != FT_SUCCESS) - { - return ret; - } - FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0xc8); - FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); - break; - default: - FNAND_TIMING_DEBUG_E("Error inter_mode is %x", instance_p->inter_mode[chip_addr]); - return FNAND_ERR_INVAILD_PARAMETER; + case FNAND_ASYN_SDR: + if (FNAND_TIMING_MODE4 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + target_timming_data = fnand_timing_asy_mode4; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(4UL) ; + } + else if (FNAND_TIMING_MODE3 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + target_timming_data = fnand_timing_asy_mode3; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; + } + else if (FNAND_TIMING_MODE2 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + target_timming_data = fnand_timing_asy_mode2; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(6UL) ; + } + else if (FNAND_TIMING_MODE1 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + target_timming_data = fnand_timing_asy_mode1; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; + } + else + { + target_timming_data = fnand_timing_asy_mode0; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(1UL) ; + } + ret = FNandMemcpyToReg16(instance_p, FNAND_ASY_TIMING0_OFFSET, 4, target_timming_data, FNAND_TIMING_ASY_NUM); + if (ret != FT_SUCCESS) + { + return ret; + } + FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 1); + break; + case FNAND_ONFI_DDR: + if (FNAND_TIMING_MODE4 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x30); + target_timming_data = fnand_timing_syn_mode4; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0xdUL) ; + } + else if (FNAND_TIMING_MODE3 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x18); + target_timming_data = fnand_timing_syn_mode3; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(5UL) ; + } + else if (FNAND_TIMING_MODE2 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x20); + target_timming_data = fnand_timing_syn_mode2; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x8UL) ; + } + else if (FNAND_TIMING_MODE1 == (instance_p->timing_mode[chip_addr] & 0xf)) + { + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x40); + target_timming_data = fnand_timing_syn_mode1; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x12UL) ; + } + else + { + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0x40); + target_timming_data = fnand_timing_syn_mode0; + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(0x12UL) ; + } + ret = FNandMemcpyToReg16(instance_p, FNAND_SYN_TIMING6_OFFSET, 4, target_timming_data, FNAND_TIMING_SYN_NUM); + if (ret != FT_SUCCESS) + { + return ret; + } + FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); + break; + case FNAND_TOG_ASYN_DDR: + value = FNAND_CTRL1_SAMPL_PHASE_MAKE(8UL); + target_timming_data = fnand_timing_tog_ddr_mode0; + ret = FNandMemcpyToReg16(instance_p, FNAND_TOG_TIMING13_OFFSET, 4, target_timming_data, FNAND_TIMING_SYN_NUM); + if (ret != FT_SUCCESS) + { + return ret; + } + FNAND_WRITEREG(config_p->base_address, FNAND_INTERVAL_OFFSET, 0xc8); + FNAND_SETBIT(config_p->base_address, FNAND_CTRL1_OFFSET, value); + break; + default: + FNAND_TIMING_DEBUG_E("Error inter_mode is %x", instance_p->inter_mode[chip_addr]); + return FNAND_ERR_INVAILD_PARAMETER; } return FT_SUCCESS; diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.h index 8289e1cc32..a0336640cf 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand_timing.h @@ -14,17 +14,26 @@ * FilePath: fnand_timing.h * Date: 2022-04-28 18:53:58 * LastEditTime: 2022-04-28 18:53:58 - * Description:  This file is for + * Description:  This file is for timings configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ -#ifndef DRIVERS_NAND_FNAND -#define DRIVERS_NAND_FNAND + +#ifndef FNAND_TIMING_H +#define FNAND_TIMING_H #include "ftypes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** * struct FNandSdrTimings - SDR NAND chip timings * @@ -118,7 +127,9 @@ struct FNandSdrTimings u32 tWW_min; }; - +#ifdef __cplusplus +} +#endif #endif diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.c index 4ba74b30e7..59ce0a10ac 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.c @@ -14,11 +14,12 @@ * FilePath: fnand_onfi.c * Date: 2022-07-05 19:10:40 * LastEditTime: 2022-07-05 19:10:41 - * Description: This file is for + * Description: This file is for onfi type nand * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -83,9 +84,9 @@ * loss). */ #define __DIVIDE(dividend, divisor) ({ \ - (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ - DIV_ROUND_UP(dividend, divisor) : \ - DIV_ROUND_UP_ULL(dividend, divisor)); \ + (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ + DIV_ROUND_UP(dividend, divisor) : \ + DIV_ROUND_UP_ULL(dividend, divisor)); \ }) #define PSEC_TO_NSEC(x) __DIVIDE(x, 1000) #define PSEC_TO_MSEC(x) __DIVIDE(x, 1000000000) @@ -115,7 +116,9 @@ static u16 FNandOnfiCrc16(u16 crc, u8 const *p, size_t len) { crc ^= *p++ << 8; for (i = 0; i < 8; i++) + { crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); + } } return crc; @@ -135,7 +138,9 @@ static void FNandSanitizeString(u8 *s, fsize_t len) for (i = 0; i < len - 1; i++) { if (s[i] < ' ' || s[i] > 127) + { s[i] = '?'; + } } } @@ -258,7 +263,7 @@ FError FNandOnfiInit(FNand *instance_p, u32 chip_addr) ret = FNandFlashReadId(instance_p, 0x20, id, sizeof(id), chip_addr); if (ret != FT_SUCCESS || strncmp(id, "ONFI", sizeof(id) - 1)) { - FNAND_ONFI_DEBUG_E("20H read id is %s ", id); + FNAND_ONFI_DEBUG_E("The id value read out from 20H is %s", id); return FNAND_NOT_FET_TOGGLE_MODE; } @@ -271,7 +276,7 @@ FError FNandOnfiInit(FNand *instance_p, u32 chip_addr) ret = FNandOnfiReadParamPage(instance_p, NULL, 0, chip_addr); if (ret != FT_SUCCESS) { - FNAND_ONFI_DEBUG_E("read device id table is error"); + FNAND_ONFI_DEBUG_E("An error occured when reading device id table"); return FNAND_NOT_FET_TOGGLE_MODE; } diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.h index aab8892209..f023aeeb11 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_onfi.h @@ -14,11 +14,12 @@ * FilePath: fnand_onfi.h * Date: 2022-07-05 19:10:47 * LastEditTime: 2022-07-05 19:10:47 - * Description: This file is for + * Description: This file is for onfi type nand * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #ifndef DRIVERS_NAND_FNAND_ONFI_H #define DRIVERS_NAND_FNAND_ONFI_H @@ -26,12 +27,16 @@ #include "ftypes.h" #include "fnand.h" +#ifdef __cplusplus +extern "C" +{ +#endif #define ONFI_CMD_READ_ID 0x90 /* ONFI Read ID \ - command */ +command */ #define ONFI_CMD_READ_PARAM_PAGE 0xEC /* ONFI Read \ Parameter Page \ - command */ +command */ #define ONFI_END_CMD_NONE 0xfff /* No End command */ @@ -103,5 +108,8 @@ struct OnfiNandGeometry u16 crc; } __attribute__((__packed__)); +#ifdef __cplusplus +} +#endif #endif // !1 \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.c index af1913f036..b402506c30 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.c @@ -14,11 +14,12 @@ * FilePath: fnand_toggle.c * Date: 2022-07-05 20:00:31 * LastEditTime: 2022-07-05 20:00:31 - * Description: This file is for + * Description: This file is for toggle nand * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #include "fnand.h" @@ -79,9 +80,9 @@ * loss). */ #define __DIVIDE(dividend, divisor) ({ \ - (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ - DIV_ROUND_UP(dividend, divisor) : \ - DIV_ROUND_UP_ULL(dividend, divisor)); \ + (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ + DIV_ROUND_UP(dividend, divisor) : \ + DIV_ROUND_UP_ULL(dividend, divisor)); \ }) #define PSEC_TO_NSEC(x) __DIVIDE(x, 1000) #define PSEC_TO_MSEC(x) __DIVIDE(x, 1000000000) @@ -119,7 +120,9 @@ static u16 FNandToggleCrc16(u16 crc, u8 const *p, size_t len) { crc ^= *p++ << 8; for (i = 0; i < 8; i++) + { crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); + } } return crc; @@ -139,7 +142,9 @@ static void FNandSanitizeString(u8 *s, fsize_t len) for (i = 0; i < len - 1; i++) { if (s[i] < ' ' || s[i] > 127) + { s[i] = '?'; + } } } @@ -259,7 +264,7 @@ FError FNandToggleInit(FNand *instance_p, u32 chip_addr) ret = FNandFlashReadId(instance_p, 0x40, id, sizeof(id), chip_addr); if (ret != FT_SUCCESS || strncmp(id, "JEDEC", sizeof(id) - 1)) { - FNAND_TOGGLE_DEBUG_E("40H read id is %s ", id); + FNAND_TOGGLE_DEBUG_E("The id value read out from 40H is %s ", id); return FNAND_NOT_FET_TOGGLE_MODE; } @@ -283,7 +288,7 @@ FError FNandToggleInit(FNand *instance_p, u32 chip_addr) ret = FNandToggleReadParamPage(instance_p, NULL, 0, chip_addr); if (ret != FT_SUCCESS) { - FNAND_TOGGLE_DEBUG_E("read device id table is error"); + FNAND_TOGGLE_DEBUG_E("An error occured when reading device id table"); return FNAND_NOT_FET_TOGGLE_MODE; } diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.h b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.h index 229a6234e6..38513ca064 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.h +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toggle.h @@ -14,24 +14,27 @@ * FilePath: fnand_toggle.h * Date: 2022-07-05 20:00:45 * LastEditTime: 2022-07-05 20:00:45 - * Description: This file is for + * Description: This file is for toggle nand * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ #ifndef DRIVERS_NAND_FNAND_TOGGLE_H #define DRIVERS_NAND_FNAND_TOGGLE_H + +#include "ftypes.h" +#include "fnand.h" + + #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fnand.h" - /* * Mandatory commands @@ -42,31 +45,31 @@ extern "C" #define TOGGLE_CMD_CHANGE_READ_COLUMN1 0x05 /* TOGGLE Change Read \ Column command (1st \ - cycle) */ +cycle) */ #define TOGGLE_CMD_CHANGE_READ_COLUMN2 0xE0 /* TOGGLE Change Read \ Column command (2nd \ - cycle) */ +cycle) */ #define TOGGLE_CMD_BLOCK_ERASE1 0x60 /* TOGGLE Block Erase \ - (1st cycle) */ +(1st cycle) */ #define TOGGLE_CMD_BLOCK_ERASE2 0xD0 /* TOGGLE Block Erase \ - (2nd cycle) */ +(2nd cycle) */ #define TOGGLE_CMD_READ_STATUS 0x70 /* TOGGLE Read status \ - command */ +command */ #define TOGGLE_CMD_PAGE_PROG1 0x80 /* TOGGLE Page Program \ command (1st cycle) \ - */ +*/ #define TOGGLE_CMD_PAGE_PROG2 0x10 /* TOGGLE Page Program \ command (2nd cycle) \ - */ +*/ #define TOGGLE_CMD_CHANGE_WRITE_COLUMN 0x85 /* TOGGLE Change Write \ - Column command */ +Column command */ #define TOGGLE_CMD_READ_ID 0x90 /* TOGGLE Read ID \ - command */ +command */ #define TOGGLE_CMD_READ_PARAM_PAGE 0xEC /* TOGGLE Read \ Parameter Page \ - command */ +command */ #define TOGGLE_CMD_RESET 0xFF /* TOGGLE Reset \ - command */ +command */ #define TOGGLE_END_CMD_NONE 0xfff /* No End command */ diff --git a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toshiba.c b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toshiba.c index c6d366c3e9..1f570217b1 100644 --- a/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toshiba.c +++ b/bsp/phytium/libraries/standalone/drivers/nand/fnand/manufacturer/fnand_toshiba.c @@ -14,11 +14,12 @@ * FilePath: fnand_toshiba.c * Date: 2022-07-06 08:32:43 * LastEditTime: 2022-07-06 08:32:44 - * Description: This file is for + * Description: This file is for toshiba nand * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/05/10 first release */ @@ -98,12 +99,12 @@ FError toshiba_nand_decode_id(FNand *instance_p, FNandId *id_p, u32 chip_addr) switch (id_p->data[1]) { - case 0xf0: - return TC58NVM9S3ETAI0_CHECK(instance_p, id_p, chip_addr) ; - break; - default: - FNAND_T_NAND_DEBUG_E("Driver not supported 0x%x device", id_p->data[1]) ; - return FNAND_ERR_NOT_MATCH; + case 0xf0: + return TC58NVM9S3ETAI0_CHECK(instance_p, id_p, chip_addr) ; + break; + default: + FNAND_T_NAND_DEBUG_E("Driver not supported 0x%x device", id_p->data[1]) ; + return FNAND_ERR_NOT_MATCH; } } diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/Kconfig b/bsp/phytium/libraries/standalone/drivers/pcie/Kconfig index 5d00a5bed0..c4476fa491 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/pcie/Kconfig @@ -4,6 +4,6 @@ menu "Pcie Configuration" bool prompt "Use F_PCIE" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.c index 470a37fc14..93f3aa6c92 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.c @@ -12,13 +12,14 @@ * * * FilePath: fpcie.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:28 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:28 + * Description: This file is for the minimum required function implementations for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ /***************************** Include Files *********************************/ @@ -45,7 +46,6 @@ #define FPCIE_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FPCIE_DEBUG_TAG, format, ##__VA_ARGS__) - /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -56,13 +56,13 @@ extern int FPcieEpCleanBar(FPcie *instance_p, u32 peu_num, u32 bar_num) ; static void FPcieShowRegion(const char *name, struct FPcieRegion *region) { - FPCIE_DEBUG_I("PCI Autoconfig: Bus %s region: [%llx-%llx],\n" - "\t\tPhysical Memory [%llx-%llx]", name, + FPCIE_DEBUG_I("Pci auto config: bus %s region: [0x%llx-0x%llx],\n" + "\t\tphysical memory [0x%llx-0x%llx]", name, (unsigned long long)region->bus_start, (unsigned long long)(region->bus_start + region->size - 1), (unsigned long long)region->phys_start, (unsigned long long)(region->phys_start + region->size - 1)); - FPCIE_DEBUG_I("bus_lower is %llx ", (unsigned long long)region->bus_lower) ; + FPCIE_DEBUG_I("Bus lower is 0x%llx", (unsigned long long)region->bus_lower) ; } /** @@ -81,29 +81,29 @@ static void FPcieRegionConfigInit(FPcie *instance_p, struct FPcieRegion *regs, u { switch (regs[i].flags) { - case FPCIE_REGION_IO: - memset(&instance_p->mem_io, 0, sizeof(struct FPcieRegion)) ; - memcpy(&instance_p->mem_io, regs, sizeof(struct FPcieRegion)) ; - instance_p->mem_io.exist_flg = FPCIE_REGION_EXIST_FLG ; - instance_p->mem_io.bus_lower = instance_p->mem_io.phys_start; - FPcieShowRegion("I/O", &instance_p->mem_io); - break; - case FPCIE_REGION_MEM: - memset(&instance_p->mem, 0, sizeof(struct FPcieRegion)) ; - memcpy(&instance_p->mem, regs, sizeof(struct FPcieRegion)) ; - instance_p->mem.exist_flg = FPCIE_REGION_EXIST_FLG ; - instance_p->mem.bus_lower = instance_p->mem.phys_start; - FPcieShowRegion("Memory", &instance_p->mem); - break; - case (PCI_REGION_PREFETCH|FPCIE_REGION_MEM): - memset(&instance_p->mem_prefetch, 0, sizeof(struct FPcieRegion)) ; - memcpy(&instance_p->mem_prefetch, regs, sizeof(struct FPcieRegion)) ; - instance_p->mem_prefetch.exist_flg = FPCIE_REGION_EXIST_FLG ; - instance_p->mem_prefetch.bus_lower = instance_p->mem_prefetch.phys_start; - FPcieShowRegion("Prefetchable Mem", &instance_p->mem_prefetch); - break; - default: - break; + case FPCIE_REGION_IO: + memset(&instance_p->mem_io, 0, sizeof(struct FPcieRegion)) ; + memcpy(&instance_p->mem_io, regs, sizeof(struct FPcieRegion)) ; + instance_p->mem_io.exist_flg = FPCIE_REGION_EXIST_FLG ; + instance_p->mem_io.bus_lower = instance_p->mem_io.phys_start; + FPcieShowRegion("I/O", &instance_p->mem_io); + break; + case FPCIE_REGION_MEM: + memset(&instance_p->mem, 0, sizeof(struct FPcieRegion)) ; + memcpy(&instance_p->mem, regs, sizeof(struct FPcieRegion)) ; + instance_p->mem.exist_flg = FPCIE_REGION_EXIST_FLG ; + instance_p->mem.bus_lower = instance_p->mem.phys_start; + FPcieShowRegion("Memory", &instance_p->mem); + break; + case (PCI_REGION_PREFETCH|FPCIE_REGION_MEM): + memset(&instance_p->mem_prefetch, 0, sizeof(struct FPcieRegion)) ; + memcpy(&instance_p->mem_prefetch, regs, sizeof(struct FPcieRegion)) ; + instance_p->mem_prefetch.exist_flg = FPCIE_REGION_EXIST_FLG ; + instance_p->mem_prefetch.bus_lower = instance_p->mem_prefetch.phys_start; + FPcieShowRegion("Prefetchable Mem", &instance_p->mem_prefetch); + break; + default: + break; } } } @@ -160,26 +160,6 @@ FError FPcieCfgInitialize(FPcie *instance_p, FPcieConfig *config_p) //用于从 instance_p->is_ready = FT_COMPONENT_IS_READY; - /* 关闭当前所有misc 中断 */ - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU0_C0); - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU0_C1); - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU0_C2); - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU1_C0); - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU1_C1); - // FPcieMiscIrqDisable(instance_p, FPCIE_PEU1_C2); - - /* 清空ep模式下所有配置地址 */ - // for (i = 0; i <= FPCIE_PEU1_C2; i++) - // { - // /* code */ - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_0); - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_1); - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_2); - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_3); - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_4); - // FPcieEpCleanBar(instance_p, i, FPCIE_BAR_5); - // } - return (FT_SUCCESS); } @@ -188,7 +168,6 @@ u32 FPcieFindCapability(FPcie *instance_p, u32 bdf, u32 cid_type, u32 cid, u32 * u32 reg_value; u32 next_cap_offset; - //u32 ret; if (cid_type == PCIE_CAP) { @@ -196,7 +175,9 @@ u32 FPcieFindCapability(FPcie *instance_p, u32 bdf, u32 cid_type, u32 cid, u32 * /* Serach in PCIe configuration space */ FPcieEcamReadConfig32bit(instance_p->config.ecam, bdf, FPCIE_CAPABILITY_LIST, ®_value); if (reg_value == 0xffffffff) + { return -1; + } next_cap_offset = (reg_value & 0xff); while (next_cap_offset) @@ -235,63 +216,63 @@ const char *FPcieClassStr(u8 class) { switch (class) { - case FPCI_CLASS_NOT_DEFINED: - return "Build before PCI Rev2.0"; - break; - case FPCI_BASE_CLASS_STORAGE: - return "Mass storage controller"; - break; - case FPCI_BASE_CLASS_NETWORK: - return "Network controller"; - break; - case FPCI_BASE_CLASS_DISPLAY: - return "Display controller"; - break; - case FPCI_BASE_CLASS_MULTIMEDIA: - return "Multimedia device"; - break; - case FPCI_BASE_CLASS_MEMORY: - return "Memory controller"; - break; - case FPCI_BASE_CLASS_BRIDGE: - return "Bridge device"; - break; - case FPCI_BASE_CLASS_COMMUNICATION: - return "Simple comm. controller"; - break; - case FPCI_BASE_CLASS_SYSTEM: - return "Base system peripheral"; - break; - case FPCI_BASE_CLASS_INPUT: - return "Input device"; - break; - case FPCI_BASE_CLASS_DOCKING: - return "Docking station"; - break; - case FPCI_BASE_CLASS_PROCESSOR: - return "Processor"; - break; - case FPCI_BASE_CLASS_SERIAL: - return "Serial bus controller"; - break; - case FPCI_BASE_CLASS_INTELLIGENT: - return "Intelligent controller"; - break; - case FPCI_BASE_CLASS_SATELLITE: - return "Satellite controller"; - break; - case FPCI_BASE_CLASS_CRYPT: - return "Cryptographic device"; - break; - case FPCI_BASE_CLASS_SIGNAL_PROCESSING: - return "DSP"; - break; - case FPCI_CLASS_OTHERS: - return "Does not fit any class"; - break; - default: - return "???"; - break; + case FPCI_CLASS_NOT_DEFINED: + return "Build before PCI Rev2.0"; + break; + case FPCI_BASE_CLASS_STORAGE: + return "Mass storage controller"; + break; + case FPCI_BASE_CLASS_NETWORK: + return "Network controller"; + break; + case FPCI_BASE_CLASS_DISPLAY: + return "Display controller"; + break; + case FPCI_BASE_CLASS_MULTIMEDIA: + return "Multimedia device"; + break; + case FPCI_BASE_CLASS_MEMORY: + return "Memory controller"; + break; + case FPCI_BASE_CLASS_BRIDGE: + return "Bridge device"; + break; + case FPCI_BASE_CLASS_COMMUNICATION: + return "Simple comm. controller"; + break; + case FPCI_BASE_CLASS_SYSTEM: + return "Base system peripheral"; + break; + case FPCI_BASE_CLASS_INPUT: + return "Input device"; + break; + case FPCI_BASE_CLASS_DOCKING: + return "Docking station"; + break; + case FPCI_BASE_CLASS_PROCESSOR: + return "Processor"; + break; + case FPCI_BASE_CLASS_SERIAL: + return "Serial bus controller"; + break; + case FPCI_BASE_CLASS_INTELLIGENT: + return "Intelligent controller"; + break; + case FPCI_BASE_CLASS_SATELLITE: + return "Satellite controller"; + break; + case FPCI_BASE_CLASS_CRYPT: + return "Cryptographic device"; + break; + case FPCI_BASE_CLASS_SIGNAL_PROCESSING: + return "DSP"; + break; + case FPCI_CLASS_OTHERS: + return "Does not fit any class"; + break; + default: + return "???"; + break; }; } @@ -308,7 +289,7 @@ int FPcieAutoRegionAllocate(struct FPcieRegion *res, pci_size_t size, if (!res) { - printf("No resource\n"); + FPCIE_DEBUG_E("No resource."); goto error; } @@ -316,21 +297,18 @@ int FPcieAutoRegionAllocate(struct FPcieRegion *res, pci_size_t size, if (addr - res->bus_start + size > res->size) { - printf("No room in resource"); + FPCIE_DEBUG_E("No room in resource."); goto error; } if (upper_32_bits(addr) && !supports_64bit) { - printf("Cannot assign 64-bit address to 32-bit-only resource\n"); + FPCIE_DEBUG_E("Cannot assign 64-bit address to 32-bit-only resource."); goto error; } res->bus_lower = addr + size; - //printf("address=0x%llx bus_lower=0x%llx\n", (unsigned long long)addr, - // (unsigned long long)res->bus_lower); - *bar = addr; return 0; @@ -362,17 +340,21 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, FPCIE_COMMAND_MASTER; for (bar = FPCIE_BASE_ADDRESS_0; - bar < FPCIE_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) + bar < FPCIE_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { /* Tickle the BAR and get the response */ if (!enum_only) + { FPcieEcamWriteConfig32bit(instance_p->config.ecam, bdf, bar, 0xffffffff); + } FPcieEcamReadConfig32bit(instance_p->config.ecam, bdf, bar, &bar_response); /* If BAR is not implemented go to the next BAR */ if (!bar_response) + { continue; + } found_mem64 = 0; @@ -382,15 +364,15 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, bar_size = ((~(bar_response & FPCIE_BASE_ADDRESS_IO_MASK)) & 0xffff) + 1; if (!enum_only) + { bar_res = io; + } - //printf("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", - // bar_nr, (unsigned long long)bar_size); } else { if ((bar_response & FPCIE_BASE_ADDRESS_MEM_TYPE_MASK) == - FPCIE_BASE_ADDRESS_MEM_TYPE_64) + FPCIE_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; @@ -407,7 +389,9 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, bar_size = ~(bar64 & FPCIE_BASE_ADDRESS_MEM_MASK) + 1; if (!enum_only) + { found_mem64 = 1; + } } else { @@ -426,10 +410,6 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, bar_res = mem; } } - - //printf("PCI Autoconfig: BAR %d, %s, size=0x%llx, ", - // bar_nr, bar_res == prefetch ? "Prf" : "Mem", - // (unsigned long long)bar_size); } if (!enum_only && FPcieAutoRegionAllocate(bar_res, bar_size, @@ -459,8 +439,6 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, cmdstat |= (bar_response & FPCIE_BASE_ADDRESS_SPACE) ? FPCIE_COMMAND_IO : FPCIE_COMMAND_MEMORY; - //printf("\n"); - bar_nr++; } @@ -478,8 +456,7 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, if (bar_response) { bar_size = -(bar_response & ~1); - //printf("PCI Autoconfig: ROM, size=%#x, ", - // (unsigned int)bar_size); + if (FPcieAutoRegionAllocate(mem, bar_size, &bar_value, false) == 0) @@ -488,7 +465,6 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, } cmdstat |= FPCIE_COMMAND_MEMORY; - //printf("\n"); } } } @@ -496,7 +472,9 @@ void FPcieAutoSetupDevice(FPcie *instance_p, u32 bdf, int bars_num, /* PCI_COMMAND_IO must be set for VGA device */ FPcieEcamReadConfig16bit(instance_p->config.ecam, bdf, FPCI_CLASS_DEVICE_REG, &class); if (class == FPCI_CLASS_DISPLAY_VGA) + { cmdstat |= FPCIE_COMMAND_IO; + } FPcieEcamWriteConfig16bit(instance_p->config.ecam, bdf, FPCIE_COMMAND_REG, cmdstat); FPcieEcamWriteConfig8bit(instance_p->config.ecam, bdf, FPCIE_CACHE_LINE_SIZE_REG, @@ -694,35 +672,36 @@ int FPcieAutoConfigDevice(FPcie *instance_p, u32 bdf) switch (class) { - case FPCI_CLASS_BRIDGE_PCI: - FPcieAutoSetupDevice(instance_p, bdf, 2, pci_mem, pci_prefetch, pci_io, - enum_only); + case FPCI_CLASS_BRIDGE_PCI: + FPcieAutoSetupDevice(instance_p, bdf, 2, pci_mem, pci_prefetch, pci_io, + enum_only); - n = FPcieHoseProbeBus(instance_p, bdf); - if (n < 0) - return n; - break; + n = FPcieHoseProbeBus(instance_p, bdf); + if (n < 0) + { + return n; + } + break; - case FPCI_CLASS_BRIDGE_CARDBUS: - /* - * just do a minimal setup of the bridge, - * let the OS take care of the rest - */ - FPcieAutoSetupDevice(instance_p, bdf, 0, pci_mem, pci_prefetch, pci_io, - enum_only); + case FPCI_CLASS_BRIDGE_CARDBUS: + /* + * just do a minimal setup of the bridge, + * let the OS take care of the rest + */ + FPcieAutoSetupDevice(instance_p, bdf, 0, pci_mem, pci_prefetch, pci_io, + enum_only); - printf("PCI Autoconfig: Found P2CardBus bridge, device %d\n", FPCIE_DEV(bdf)); + FPCIE_DEBUG_I("PCI auto config: Found P2CardBus bridge, device %d.", FPCIE_DEV(bdf)); - break; + break; - case FPCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ - printf("PCI AutoConfig: Found PowerPC device\n"); - /* fall through */ + case FPCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ + FPCIE_DEBUG_I("PCI auto config: Found PowerPC device."); - default: - FPcieAutoSetupDevice(instance_p, bdf, 6, pci_mem, pci_prefetch, pci_io, - enum_only); - break; + default: + FPcieAutoSetupDevice(instance_p, bdf, 6, pci_mem, pci_prefetch, pci_io, + enum_only); + break; } return FT_SUCCESS; @@ -742,10 +721,12 @@ FError FPcieBindBusDevices(FPcie *instance_p, u32 bus_num, u32 parent_bdf, struc u32 data; char buf_bdf_print[20]; found_multi = false; - end = FPCIE_BDF(bus_num, FT_PCIE_CFG_MAX_NUM_OF_DEV - 1, - FT_PCIE_CFG_MAX_NUM_OF_FUN - 1); - for (bdf = FPCIE_BDF(bus_num, 0, 0); bdf <= end; //使用bus的seq成员来进行扫描,其实相当于secondory_bus号 - bdf += FPCIE_BDF(0, 0, 1)) + end = FPCIE_BDF(bus_num, FPCIE_CFG_MAX_NUM_OF_DEV - 1, + FPCIE_CFG_MAX_NUM_OF_FUN - 1); + + /* 使用bus的seq成员来进行扫描,其实相当于secondory_bus号 */ + for (bdf = FPCIE_BDF(bus_num, 0, 0); bdf <= end; + bdf += FPCIE_BDF(0, 0, 1)) { u32 class; @@ -759,23 +740,32 @@ FError FPcieBindBusDevices(FPcie *instance_p, u32 bus_num, u32 parent_bdf, struc } if (!FPCIE_FUNC(bdf)) + { found_multi = false; + } if (FPCIE_FUNC(bdf) && !found_multi) + { continue; + } /* Check only the first access, we don't expect problems */ FPcieEcamReadConfig16bit(instance_p->config.ecam, bdf, FPCIE_VENDOR_REG, &vendor) ; if (vendor == 0xffff || vendor == 0x0000) + { continue; + } FPcieEcamReadConfig8bit(instance_p->config.ecam, bdf, FPCIE_HEADER_TYPE_REG, &header_type) ; if (!FPCIE_FUNC(bdf)) + { found_multi = header_type & 0x80; - - FPcieEcamReadConfig16bit(instance_p->config.ecam, bdf, FPCIE_DEVICE_ID_REG, &device) ; //读取deviceid - FPcieEcamReadConfig32bit(instance_p->config.ecam, bdf, FPCI_CLASS_REVISION, &class) ; //读取classcode + } + + /* 读取deviceid, classcode */ + FPcieEcamReadConfig16bit(instance_p->config.ecam, bdf, FPCIE_DEVICE_ID_REG, &device) ; + FPcieEcamReadConfig32bit(instance_p->config.ecam, bdf, FPCI_CLASS_REVISION, &class) ; class >>= 8; FPcieEcamReadConfig8bit(instance_p->config.ecam, bdf, FPCIE_CLASS_CODE_REG, &class_show) ; diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.h b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.h index c8ca7077dc..30f0191121 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.h +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie.h @@ -12,21 +12,18 @@ * * * FilePath: fpcie.h - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:37 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:37 + * Description: This file is for detailed description of the device and driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ - -#ifndef DRIVERS_FPCIE_H -#define DRIVERS_FPCIE_H - - - +#ifndef FPCIE_H +#define FPCIE_H /************************** Constant Definitions *****************************/ @@ -36,11 +33,6 @@ /************************** Function Prototypes ******************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - /***************************** Include Files *********************************/ #include "ftypes.h" @@ -48,6 +40,11 @@ extern "C" #include "fpcie_dma.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #ifdef __aarch64__ #define CONFIG_SYS_PCI_64BIT 1 #endif @@ -174,16 +171,16 @@ typedef struct uintptr_t peu0_config_address; uintptr_t peu1_config_address; - uintptr_t control_c0_address; //0x29900000 - uintptr_t control_c1_address; //0x29910000 + uintptr_t control_c0_address; + uintptr_t control_c1_address; uintptr_t control_c2_address; uintptr_t control_c3_address; uintptr_t control_c4_address; uintptr_t control_c5_address; -#ifdef FT_PCI_INTX_EOI - uintptr_t intx_peux_stat_address[FT_PCI_INTX_SATA_NUM] ; - uintptr_t intx_control_eux_cx_address[FT_PCI_INTX_CONTROL_NUM] ; +#ifdef FPCI_INTX_EOI + uintptr_t intx_peux_stat_address[FPCI_INTX_SATA_NUM] ; + uintptr_t intx_control_eux_cx_address[FPCI_INTX_CONTROL_NUM] ; #endif u32 io_base_addr; diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_common.h b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_common.h index 3b7c1efef7..74d914fe23 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_common.h +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_common.h @@ -12,27 +12,27 @@ * * * FilePath: fpcie_common.h - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:57:24 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:57:24 + * Description: This file is for pcie common features definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ +#ifndef FPCIE_COMMON_H +#define FPCIE_COMMON_H -#ifndef DRIVERS_FPCIE_COMMON_H -#define DRIVERS_FPCIE_COMMON_H +#include "fpcie_hw.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" { #endif -#include "fpcie_hw.h" -#include "fkernel.h" - /******************** Macros (Inline Functions) Definitions *******************/ /* Device classes and subclasses */ @@ -226,13 +226,11 @@ extern "C" #define FPCIE_HEADER_TYPE_REG 0x0e /* 8 bits */ - #define FPCIE_REVISION_ID_REG 0x08 /* Revision ID */ #define FPCIE_CLASS_PROG_REG 0x09 /* Reg. Level Programming Interface */ #define FPCIE_CLASS_DEVICE_REG 0x0a /* Device class */ #define FPCIE_CLASS_CODE_REG 0x0b /* Device class code */ - #define FPCIE_PREF_MEMORY_BASE_REG 0x24 /* Prefetchable memory range behind */ #define FPCIE_PREF_MEMORY_LIMIT_REG 0x26 #define FPCIE_PREF_LIMIT_UPPER32_REG 0x2c @@ -241,18 +239,14 @@ extern "C" #define FPCIE_PREF_RANGE_TYPE_64 0x01 #define FPCIE_PREF_RANGE_MASK ~0x0f - #define FPCI_CLASS_BRIDGE_PCI 0x0604 #define FPCI_CLASS_BRIDGE_CARDBUS 0x0607 #define FPCI_CLASS_PROCESSOR_POWERPC 0x0b20 #define FPCI_CLASS_DISPLAY_VGA 0x0300 - - #define FPCIE_CFG_FUN_NOT_IMP_MASK 0xFFFF #define FPCIE_CFG_HEADER_TYPE_MASK 0x007F0000 - /* * Base addresses specify locations in memory or I/O space. * Decoded size can be determined by writing a value of @@ -479,10 +473,6 @@ extern "C" #define FPCI_CAP_ID_EA 0x14 /* PCI Enhanced Allocation */ #define FPCI_CAP_ID_MAX PCI_CAP_ID_EA -/* Extended Capabilities (PCI-X 2.0 and Express) */ -//#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) -//#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) -//#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) #define FPCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ #define FPCI_EXT_CAP_ID_VC 0x02 /* Virtual Channel Capability */ @@ -524,8 +514,6 @@ extern "C" #define FPCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET 0x28 #define FPCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING 0x20 - - /* * Address Translation Registers */ diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_config.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_config.c index 1fc5f4ad6a..79c97b8ca2 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_config.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_config.c @@ -12,19 +12,19 @@ * * * FilePath: fpcie_config.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:57:30 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:57:30 + * Description: This file is for pcie miscellaneous interrupt enable or disable. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ #include "fpcie.h" #include "fpcie_hw.h" - /***************************** Include Files *********************************/ /************************** Constant Definitions *****************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.c index 721e8d2d25..e601dbd7d7 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.c @@ -12,13 +12,14 @@ * * * FilePath: fpcie_dma.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:57:38 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:57:38 + * Description: This file is for pcie dma implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ @@ -28,7 +29,7 @@ #include "ftypes.h" #include "fcache.h" #include "fkernel.h" - +#include "fdebug.h" /***************************** Include Files *********************************/ /************************** Constant Definitions *****************************/ @@ -39,7 +40,7 @@ /***************** Macros (Inline Functions) Definitions *********************/ -#include "fdebug.h" + #define FPCIE_DMA_DEBUG_TAG "FPCIE_DMA" #define FPCIE_DMA_ERROR(format, ...) FT_DEBUG_PRINT_E(FPCIE_DMA_DEBUG_TAG, format, ##__VA_ARGS__) #define FPCIE_DMA_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FPCIE_DMA_DEBUG_TAG, format, ##__VA_ARGS__) @@ -149,15 +150,15 @@ void FPcieDmaWrite(uintptr bar_address, struct FPcieDmaDescriptor *desc) */ FError FPcieDmaPollDone(struct FPcieDmaDescriptor *desc, u32 wait_cnt) { - FPCIE_DMA_DEBUG_I("desc axi_bus_status :[0x%02x]", desc->axi_bus_status); - FPCIE_DMA_DEBUG_I("desc pcie_bus_status:[0x%02x]", desc->pcie_bus_status); - FPCIE_DMA_DEBUG_I("desc channel_status :[0x%02x]", desc->channel_status); + FPCIE_DMA_DEBUG_I("Desc axi_bus_status :[0x%02x].", desc->axi_bus_status); + FPCIE_DMA_DEBUG_I("Desc pcie_bus_status:[0x%02x].", desc->pcie_bus_status); + FPCIE_DMA_DEBUG_I("Desc channel_status :[0x%02x].", desc->channel_status); while (wait_cnt > 0) { if (desc->channel_status == 0x1) { - FPCIE_DMA_DEBUG_I("dma channel transfer done "); + FPCIE_DMA_DEBUG_I("Dma channel transfer done."); return FT_SUCCESS; } wait_cnt--; diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.h b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.h index 6e0d54bdba..999b22bbe7 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.h +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_dma.h @@ -12,24 +12,25 @@ * * * FilePath: fpcie_dma.h - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:57:51 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:57:51 + * Description: This file is for pcie dma definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ -#ifndef DRIVERS_FPCIE_DMA_H -#define DRIVERS_FPCIE_DMA_H +#ifndef FPCIE_DMA_H +#define FPCIE_DMA_H + +#include "ftypes.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" - /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_ep.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_ep.c index cad384e18c..a0d7dc7b0e 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_ep.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_ep.c @@ -12,13 +12,14 @@ * * * FilePath: fpcie_ep.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:57:59 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:57:59 + * Description: This file is for pcie endpoint device operation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ #include "fpcie.h" @@ -49,8 +50,6 @@ /************************** Function Prototypes ******************************/ - - int FPcieEpSetBar(FPcie *instance_p, u32 peu_num, u32 bar_num, u64 bar_mem_addr, u64 bar_mem_size, int flags) { u32 addr0, addr1, reg, cfg, b, aperture, ctrl; @@ -79,19 +78,31 @@ int FPcieEpSetBar(FPcie *instance_p, u32 peu_num, u32 bar_num, u64 bar_mem_addr, boolean is_64bits = sz > SZ_2G; if (is_64bits && (bar_num & 1)) + { return FPCIE_ERR_INVALID_PARAM; + } if (is_64bits && !(flags & FPCIE_BASE_ADDRESS_MEM_TYPE_64)) + { flags |= FPCIE_BASE_ADDRESS_MEM_TYPE_64; + } if (is_64bits && is_prefetch) + { ctrl = FPCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS; + } else if (is_prefetch) + { ctrl = FPCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS; + } else if (is_64bits) + { ctrl = FPCIE_LM_BAR_CFG_CTRL_MEM_64BITS; + } else + { ctrl = FPCIE_LM_BAR_CFG_CTRL_MEM_32BITS; + } } addr0 = LOWER_32_BITS(bar_mem_addr); diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_g.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_g.c index 2f05d51696..a0154c3837 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_g.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_g.c @@ -12,13 +12,14 @@ * * * FilePath: fpcie_g.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:58:07 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:58:07 + * Description: This file is for pcie static configuration implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ @@ -28,47 +29,47 @@ #include "sdkconfig.h" -FPcieConfig FPcieConfigTable[FT_PCIE_NUM] = +FPcieConfig FPcieConfigTable[FPCIE_NUM] = { { - .instance_id = FT_PCIE0_ID, /* Id of device*/ - .irq_num = FT_PCIE0_MISC_IRQ_NUM, // Irq number - .ecam = FT_PCI_CONFIG_BASEADDR, /* The Memory way */ - .peu0_config_address = FT_PCI_EU0_CONFIG_BASEADDR, - .peu1_config_address = FT_PCI_EU1_CONFIG_BASEADDR, - .control_c0_address = FT_PCI_EU0_C0_CONTROL_BASEADDR, - .control_c1_address = FT_PCI_EU0_C1_CONTROL_BASEADDR, - .control_c2_address = FT_PCI_EU0_C2_CONTROL_BASEADDR, - .control_c3_address = FT_PCI_EU1_C0_CONTROL_BASEADDR, - .control_c4_address = FT_PCI_EU1_C1_CONTROL_BASEADDR, - .control_c5_address = FT_PCI_EU1_C2_CONTROL_BASEADDR, -#ifdef FT_PCI_INTX_EOI + .instance_id = FPCIE0_ID, /* Id of device*/ + .irq_num = FPCIE0_MISC_IRQ_NUM, // Irq number + .ecam = FPCI_CONFIG_BASE_ADDR, /* The Memory way */ + .peu0_config_address = FPCI_EU0_CONFIG_BASE_ADDR, + .peu1_config_address = FPCI_EU1_CONFIG_BASE_ADDR, + .control_c0_address = FPCI_EU0_C0_CONTROL_BASE_ADDR, + .control_c1_address = FPCI_EU0_C1_CONTROL_BASE_ADDR, + .control_c2_address = FPCI_EU0_C2_CONTROL_BASE_ADDR, + .control_c3_address = FPCI_EU1_C0_CONTROL_BASE_ADDR, + .control_c4_address = FPCI_EU1_C1_CONTROL_BASE_ADDR, + .control_c5_address = FPCI_EU1_C2_CONTROL_BASE_ADDR, +#ifdef FPCI_INTX_EOI .intx_peux_stat_address = { - [0] = FT_PCI_INTX_PEU0_STAT, - [1] = FT_PCI_INTX_PEU1_STAT, + [0] = FPCI_INTX_PEU0_STAT, + [1] = FPCI_INTX_PEU1_STAT, }, .intx_control_eux_cx_address = { - [0] = FT_PCI_INTX_EU0_C0_CONTROL, - [1] = FT_PCI_INTX_EU0_C1_CONTROL, - [2] = FT_PCI_INTX_EU0_C2_CONTROL, - [3] = FT_PCI_INTX_EU1_C0_CONTROL, - [4] = FT_PCI_INTX_EU1_C1_CONTROL, - [5] = FT_PCI_INTX_EU1_C2_CONTROL, + [0] = FPCI_INTX_EU0_C0_CONTROL, + [1] = FPCI_INTX_EU0_C1_CONTROL, + [2] = FPCI_INTX_EU0_C2_CONTROL, + [3] = FPCI_INTX_EU1_C0_CONTROL, + [4] = FPCI_INTX_EU1_C1_CONTROL, + [5] = FPCI_INTX_EU1_C2_CONTROL, }, #endif - .io_base_addr = FT_PCI_IO_CONFIG_BASEADDR, - .io_size = FT_PCI_IO_CONFIG_REG_LENGTH, - .npmem_base_addr = FT_PCI_MEM32_BASEADDR, - .npmem_size = FT_PCI_MEM32_REG_LENGTH, - .pmem_base_addr = FT_PCI_MEM64_BASEADDR, /* Prefetchable memory */ - .pmem_size = FT_PCI_MEM64_REG_LENGTH, - .inta_irq_num = FT_PCI_INTA_IRQ_NUM, - .intb_irq_num = FT_PCI_INTB_IRQ_NUM, - .intc_irq_num = FT_PCI_INTC_IRQ_NUM, - .intd_irq_num = FT_PCI_INTD_IRQ_NUM, - .need_skip = FT_PCI_NEED_SKIP + .io_base_addr = FPCI_IO_CONFIG_BASE_ADDR, + .io_size = FPCI_IO_CONFIG_REG_LENGTH, + .npmem_base_addr = FPCI_MEM32_BASE_ADDR, + .npmem_size = FPCI_MEM32_REG_LENGTH, + .pmem_base_addr = FPCI_MEM64_BASE_ADDR, /* Prefetchable memory */ + .pmem_size = FPCI_MEM64_REG_LENGTH, + .inta_irq_num = FPCI_INTA_IRQ_NUM, + .intb_irq_num = FPCI_INTB_IRQ_NUM, + .intc_irq_num = FPCI_INTC_IRQ_NUM, + .intd_irq_num = FPCI_INTD_IRQ_NUM, + .need_skip = FPCI_NEED_SKIP } }; diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.c index 3850bab7c5..d8beaedfac 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.c @@ -13,12 +13,13 @@ * * FilePath: fpcie_hw.c * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:58:12 - * Description:  This files is for + * LastEditTime: 2022-08-18 08:58:12 + * Description: This file is for pcie register operation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ #include "fpcie_hw.h" @@ -116,7 +117,9 @@ FError FPcieSkipDevice(uintptr ecam_addr, s32 bdf) { pos = FPCIE_READREG_BYTE(addr, pos) ; if (pos < 0x40)/* 超过Capability Pointer所代表的空间offset最大范围 */ + { break; + } pos &= ~3 ; /* offset 第两位对齐 */ id = FPCIE_READREG_BYTE(addr, pos) ; /* PCI Express Cap ID */ if (id == 0xff) @@ -151,12 +154,12 @@ static s32 FPcieGetFf(enum FPcieSize size) { switch (size) { - case FPCIE_SIZE_8: - return 0xff; - case FPCIE_SIZE_16: - return 0xffff; - default: - return 0xffffffff; + case FPCIE_SIZE_8: + return 0xff; + case FPCIE_SIZE_16: + return 0xffff; + default: + return 0xffffffff; } } diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.h b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.h index b6c1c1906c..96a4c5d0b0 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_hw.h @@ -12,28 +12,28 @@ * * * FilePath: fpcie_hw.h - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:58:22 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:58:22 + * Description: This file is for pcie register definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ +#ifndef FPCIE_HW_H +#define FPCIE_HW_H -#ifndef DRIVERS_FPCIE_HW_H -#define DRIVERS_FPCIE_HW_H +#include "ftypes.h" +#include "fio.h" +#include "ferror_code.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fio.h" -#include "ferror_code.h" - /***************************** Include Files *********************************/ /************************** Constant Definitions *****************************/ @@ -226,8 +226,6 @@ extern "C" #define FPCIE_ECAM_FUN_SHIFT 12 /**< Function Number Shift Value */ #define FPCIE_ECAM_REG_SHIFT 2 /**< Register Number Shift Value */ #define FPCIE_ECAM_BYT_SHIFT 0 /**< Byte Offset Shift Value */ -/*@}*/ - #define FPCIE_BUS(d) (((d) >> 16) & 0xff) /* @@ -318,7 +316,7 @@ void FPcieEcamWriteConfig16bit(uintptr ecam_addr, s32 bdf, u32 offset, u16 value void FPcieEcamWriteConfig32bit(uintptr ecam_addr, s32 bdf, u32 offset, u32 value); -FError FPcieSkipDevice(uintptr ecam_addr, s32 bdf) ; +FError FPcieSkipDevice(uintptr ecam_addr, s32 bdf); #ifdef __cplusplus } diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.c similarity index 64% rename from bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.c rename to bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.c index bcf0992e11..1bc17a7051 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.c @@ -11,18 +11,17 @@ * See the Phytium Public License for more details. * * - * FilePath: fpcir_intx.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:42 - * Description:  This files is for + * FilePath: fpcie_intr.c + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:42 + * Description: This file is for pcie interrupt handler implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ - - /***************************** Include Files *********************************/ #include "fpcie.h" #include "fpcie_common.h" @@ -30,7 +29,6 @@ #include "fparameters.h" #include "fdebug.h" - /***************** Macros (Inline Functions) Definitions *********************/ #define FPCIE_INTX_DEBUG_TAG "FPCIE_INTX" @@ -89,36 +87,36 @@ FError FPcieIntxRegiterIrqHandler(FPcie *instance_p, FPcieEcamReadConfig8bit(instance_p->config.ecam, bdf, FPCIE_INTERRUPT_PIN_REG, &interrupt_pin) ; switch (interrupt_pin) { - case 0x1: /* INTA# */ - interrupt_line = instance_p->config.inta_irq_num ; - instance_p->inta_fun[i] = *intx_fun_p; //中断函数,写入的是pcie instance的成员,一个pcie rc只有一个中断处理函数? - instance_p->inta_fun[i].bdf = bdf; //一个中断函数对应一个bdf号 - break ; - case 0x2: /* INTB# */ - interrupt_line = instance_p->config.intb_irq_num ; - instance_p->intb_fun[i] = *intx_fun_p; - instance_p->intb_fun[i].bdf = bdf; - break ; - case 0x3: /* INTC# */ - interrupt_line = instance_p->config.intc_irq_num ; - instance_p->intc_fun[i] = *intx_fun_p; - instance_p->intc_fun[i].bdf = bdf; - break ; - case 0x4: /* INTD# */ - interrupt_line = instance_p->config.intd_irq_num ; - instance_p->intd_fun[i] = *intx_fun_p; - instance_p->intd_fun[i].bdf = bdf; - break ; - default: - FPCIE_INTX_DEBUG_E("Error interrupt pin") ; - return FPCIE_NOT_FOUND; + case 0x1: /* INTA# */ + interrupt_line = instance_p->config.inta_irq_num ; + instance_p->inta_fun[i] = *intx_fun_p; //中断函数,写入的是pcie instance的成员,一个pcie rc只有一个中断处理函数? + instance_p->inta_fun[i].bdf = bdf; //一个中断函数对应一个bdf号 + break ; + case 0x2: /* INTB# */ + interrupt_line = instance_p->config.intb_irq_num ; + instance_p->intb_fun[i] = *intx_fun_p; + instance_p->intb_fun[i].bdf = bdf; + break ; + case 0x3: /* INTC# */ + interrupt_line = instance_p->config.intc_irq_num ; + instance_p->intc_fun[i] = *intx_fun_p; + instance_p->intc_fun[i].bdf = bdf; + break ; + case 0x4: /* INTD# */ + interrupt_line = instance_p->config.intd_irq_num ; + instance_p->intd_fun[i] = *intx_fun_p; + instance_p->intd_fun[i].bdf = bdf; + break ; + default: + FPCIE_INTX_DEBUG_E("Error interrupt pin.") ; + return FPCIE_NOT_FOUND; } FPcieEcamWriteConfig8bit(instance_p->config.ecam, bdf, FPCIE_INTERRUPT_LINE_REG, interrupt_line) ; } else { - FPCIE_INTX_DEBUG_E("Pcie intx not match header type") ; + FPCIE_INTX_DEBUG_E("Pcie intx not match header type.") ; return FPCIE_NOT_FOUND; } @@ -138,21 +136,21 @@ static void FPcieIntxCallback(FPcie *instance_p, u8 INTx_NUM) { switch (INTx_NUM) { - case INTA: - instance_p->inta_fun[i].IntxCallBack(instance_p->inta_fun[i].args); - break; - case INTB: - instance_p->intb_fun[i].IntxCallBack(instance_p->intb_fun[i].args); - break; - case INTC: - instance_p->intc_fun[i].IntxCallBack(instance_p->intc_fun[i].args); - break; - case INTD: - instance_p->intd_fun[i].IntxCallBack(instance_p->intd_fun[i].args); - break; - default: - printf("%s: error intx num\n", __func__); - break; + case INTA: + instance_p->inta_fun[i].IntxCallBack(instance_p->inta_fun[i].args); + break; + case INTB: + instance_p->intb_fun[i].IntxCallBack(instance_p->intb_fun[i].args); + break; + case INTC: + instance_p->intc_fun[i].IntxCallBack(instance_p->intc_fun[i].args); + break; + case INTD: + instance_p->intd_fun[i].IntxCallBack(instance_p->intd_fun[i].args); + break; + default: + FPCIE_INTX_DEBUG_E("%s: error intx num.", __func__); + break; } } @@ -163,7 +161,7 @@ static void FPcieIntxCallback(FPcie *instance_p, u8 INTx_NUM) static void FPcieIntxIrqEoi(FPcie *instance_p, u32 intx_idx) { -#ifdef FT_PCI_INTX_EOI +#ifdef FPCI_INTX_EOI u32 status = 0 ; u32 istatus = 0, imask = 0 ; int i ; @@ -171,7 +169,7 @@ static void FPcieIntxIrqEoi(FPcie *instance_p, u32 intx_idx) imask = 1 << (3 - intx_idx); istatus = (1 << intx_idx) << 24; - for (i = 0; i < FT_PCI_INTX_CONTROL_NUM; i++, status >>= 4) + for (i = 0; i < FPCI_INTX_CONTROL_NUM; i++, status >>= 4) { if (imask & status) { @@ -200,25 +198,23 @@ void FPcieIntxIrqHandler(s32 vector, void *args) //中断响应函数 switch (vector) { - case FT_PCI_INTA_IRQ_NUM: //如果响应的是INTA中断,则调用pcie_obj中INTA的中断处理函数 - FPcieIntxCallback(instance_p, INTA) ; - FPcieIntxIrqEoi(instance_p, 0) ; - break; - case FT_PCI_INTB_IRQ_NUM: - FPcieIntxCallback(instance_p, INTA) ; - FPcieIntxIrqEoi(instance_p, 1) ; - break; - case FT_PCI_INTC_IRQ_NUM: - FPcieIntxCallback(instance_p, INTA) ; - FPcieIntxIrqEoi(instance_p, 2) ; - break; - case FT_PCI_INTD_IRQ_NUM: - FPcieIntxCallback(instance_p, INTA) ; - FPcieIntxIrqEoi(instance_p, 3) ; - break; - default: - break; + case FPCI_INTA_IRQ_NUM: //如果响应的是INTA中断,则调用pcie_obj中INTA的中断处理函数 + FPcieIntxCallback(instance_p, INTA) ; + FPcieIntxIrqEoi(instance_p, 0) ; + break; + case FPCI_INTB_IRQ_NUM: + FPcieIntxCallback(instance_p, INTA) ; + FPcieIntxIrqEoi(instance_p, 1) ; + break; + case FPCI_INTC_IRQ_NUM: + FPcieIntxCallback(instance_p, INTA) ; + FPcieIntxIrqEoi(instance_p, 2) ; + break; + case FPCI_INTD_IRQ_NUM: + FPcieIntxCallback(instance_p, INTA) ; + FPcieIntxIrqEoi(instance_p, 3) ; + break; + default: + break; } } - - diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.h b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.h similarity index 82% rename from bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.h rename to bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.h index d2dcbc397c..413d2dd839 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcir_intx.h +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_intr.h @@ -11,19 +11,20 @@ * See the Phytium Public License for more details. * * - * FilePath: fpcir_intx.h - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:47 - * Description:  This files is for + * FilePath: fpcie_intr.h + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:47 + * Description: This file is for pcie interrupt handler definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ -#ifndef DIRVERS_PCIE_FPCIE_FPCIE_INTX_H -#define DIRVERS_PCIE_FPCIE_FPCIE_INTX_H +#ifndef FPCIE_INTR_H +#define FPCIE_INTR_H /************************** Constant Definitions *****************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_misc.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_misc.c index 77340b588a..cea658c0fd 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_misc.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_misc.c @@ -12,13 +12,14 @@ * * * FilePath: fpcie_misc.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:17 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:17 + * Description: This file is for pcie miscellaneous interrupt operation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ @@ -43,8 +44,6 @@ #define FPCIE_INTR_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FPCIE_INTR_DEBUG_TAG, format, ##__VA_ARGS__) /************************** Function Prototypes ******************************/ - - FError FPcieMiscSetHandler(FPcie *instance_p, u32 handler_type, void *func_pointer, void *call_back_ref) { @@ -55,29 +54,29 @@ FError FPcieMiscSetHandler(FPcie *instance_p, u32 handler_type, switch (handler_type) { - case FPCIE_HANDLER_DMASEND: - status = FT_SUCCESS; - instance_p->fpcie_dma_tx_cb = ((FPcieIrqCallBack)(void *)func_pointer); - instance_p->dma_tx_args = call_back_ref; - break; - case FPCIE_HANDLER_DMARECV: - status = FT_SUCCESS; - instance_p->fpcie_dma_rx_cb = ((FPcieIrqCallBack)(void *)func_pointer); - instance_p->dma_rx_args = call_back_ref; - break; - case FPCIE_HANDLER_DMASEND_ERROR: - status = FT_SUCCESS; - instance_p->fpcie_dma_tx_error_cb = ((FPcieIrqCallBack)(void *)func_pointer); - instance_p->dma_tx_error_args = call_back_ref; - break; - case FPCIE_HANDLER_DMARECV_ERROR: - status = FT_SUCCESS; - instance_p->fpcie_dma_rx_error_cb = ((FPcieIrqCallBack)(void *)func_pointer); - instance_p->dma_rx_error_args = call_back_ref; - break; - default: - status = FPCIE_ERR_INVALID_PARAM; - break; + case FPCIE_HANDLER_DMASEND: + status = FT_SUCCESS; + instance_p->fpcie_dma_tx_cb = ((FPcieIrqCallBack)(void *)func_pointer); + instance_p->dma_tx_args = call_back_ref; + break; + case FPCIE_HANDLER_DMARECV: + status = FT_SUCCESS; + instance_p->fpcie_dma_rx_cb = ((FPcieIrqCallBack)(void *)func_pointer); + instance_p->dma_rx_args = call_back_ref; + break; + case FPCIE_HANDLER_DMASEND_ERROR: + status = FT_SUCCESS; + instance_p->fpcie_dma_tx_error_cb = ((FPcieIrqCallBack)(void *)func_pointer); + instance_p->dma_tx_error_args = call_back_ref; + break; + case FPCIE_HANDLER_DMARECV_ERROR: + status = FT_SUCCESS; + instance_p->fpcie_dma_rx_error_cb = ((FPcieIrqCallBack)(void *)func_pointer); + instance_p->dma_rx_error_args = call_back_ref; + break; + default: + status = FPCIE_ERR_INVALID_PARAM; + break; } return status; } @@ -121,8 +120,8 @@ void FPcieMiscIrq(s32 vector, void *args) control_address = instance_p->config.control_c5_address; } - FPCIE_INTR_DEBUG_I("pcie misc irq!"); - FPCIE_INTR_DEBUG_I("pcie dma irq status : 0x%08lx", FPCIE_READREG(control_address, FPCIE_REG_DMA_INT_STATUS_OFFSET)); + FPCIE_INTR_DEBUG_I("Pcie misc irq!"); + FPCIE_INTR_DEBUG_I("Pcie dma irq status : 0x%08lx", FPCIE_READREG(control_address, FPCIE_REG_DMA_INT_STATUS_OFFSET)); reg_value = FPCIE_READREG(control_address, FPCIE_REG_DMA_INT_STATUS_OFFSET); diff --git a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_sinit.c b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_sinit.c index f972582888..102f1e0d12 100644 --- a/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/pcie/fpcie/fpcie_sinit.c @@ -12,20 +12,20 @@ * * * FilePath: fpcie_sinit.c - * Date: 2022-02-10 14:55:11 - * LastEditTime: 2022-02-18 08:59:22 - * Description:  This files is for + * Date: 2022-08-10 14:55:11 + * LastEditTime: 2022-08-18 08:59:22 + * Description: This file is for pcie static variables implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/8/18 init commit */ - #include "fpcie.h" #include "fparameters.h" -extern FPcieConfig FPcieConfigTable[FT_PCIE_NUM]; +extern FPcieConfig FPcieConfigTable[FPCIE_NUM]; FPcieConfig *FPcieLookupConfig(u32 instance_id) @@ -33,7 +33,7 @@ FPcieConfig *FPcieLookupConfig(u32 instance_id) FPcieConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)FT_PCIE_NUM; index++) + for (index = 0; index < (u32)FPCIE_NUM; index++) { if (FPcieConfigTable[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/Kconfig b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/Kconfig index 0d8106298f..02c30d70d6 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/Kconfig @@ -3,5 +3,5 @@ config ENABLE_FGPIO bool prompt "Use FGPIO" default n - - + + diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.c b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.c index 37b5eab09c..5bb2edbdca 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.c +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.c @@ -19,7 +19,8 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ @@ -59,7 +60,7 @@ FError FGpioCfgInitialize(FGpio *const instance, const FGpioConfig *const config if (0 == config->base_addr) { - FGPIO_ERROR("invalid base address !!!"); + FGPIO_ERROR("Invalid base address !!!"); return FGPIO_ERR_INVALID_PARA; } @@ -68,6 +69,9 @@ FError FGpioCfgInitialize(FGpio *const instance, const FGpioConfig *const config instance->config = *config; } + /* mask interrupt for all pins */ + FGpioWriteReg32(instance->config.base_addr, FGPIO_INTMASK_OFFSET, FGPIO_INTR_PORTA_MASKALL); + instance->is_ready = FT_COMPONENT_IS_READY; return FGPIO_SUCCESS; } @@ -113,12 +117,12 @@ FError FGpioPinInitialize(FGpio *const instance, FGpioPin *const pin_instance, const FGpioPinId index) { FASSERT(instance && pin_instance); - FASSERT_MSG(index.port < FGPIO_PORT_NUM, "invalid gpio port %d", index); - FASSERT_MSG(index.pin < FGPIO_PIN_NUM, "invalid gpio pin %d", index); + FASSERT_MSG(index.port < FGPIO_PORT_NUM, "Invalid gpio port %d", index); + FASSERT_MSG(index.pin < FGPIO_PIN_NUM, "Invalid gpio pin %d", index); if (FT_COMPONENT_IS_READY != instance->is_ready) { - FGPIO_ERROR("gpio instance not yet init !!!"); + FGPIO_ERROR("gpio instance is not yet inited !!!"); return FGPIO_ERR_NOT_INIT; } @@ -151,14 +155,16 @@ void FGpioPinDeInitialize(FGpioPin *const pin) FGpio *const instance = pin->instance; if ((NULL == instance) || (FT_COMPONENT_IS_READY != instance->is_ready) || - (FT_COMPONENT_IS_READY != pin->is_ready)) + (FT_COMPONENT_IS_READY != pin->is_ready)) { - FGPIO_ERROR("gpio instance not yet init !!!"); + FGPIO_ERROR("gpio instance is not yet inited !!!"); return; } if (FGPIO_DIR_INPUT == FGpioGetDirection(pin)) - FGpioSetInterruptMask(pin, FALSE); /* 关闭引脚中断 */ + { + FGpioSetInterruptMask(pin, FALSE); /* 关闭引脚中断 */ + } FGpioPinId index = pin->index; FASSERT_MSG(instance->pins[index.port][index.pin] == pin, "invalid pin instance"); @@ -269,7 +275,7 @@ void FGpioSetDirection(FGpioPin *const pin, FGpioDirection dir) FASSERT(pin); FGpio *const instance = pin->instance; FASSERT(instance); - FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not yet init !!!"); + FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not is yet inited !!!"); u32 reg_val; FGpioPinId index = pin->index; uintptr base_addr = instance->config.base_addr; @@ -384,7 +390,7 @@ FError FGpioSetOutputValue(FGpioPin *const pin, const FGpioPinVal output) FASSERT(pin); FGpio *const instance = pin->instance; FASSERT(instance); - FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not yet init !!!"); + FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance is not yet inited !!!"); FGpioPinId index = pin->index; u32 base_addr = instance->config.base_addr; @@ -392,7 +398,7 @@ FError FGpioSetOutputValue(FGpioPin *const pin, const FGpioPinVal output) if (FGPIO_DIR_OUTPUT != FGpioGetDirection(pin)) { - FGPIO_ERROR("need to set GPIO direction as OUTPUT first !!!"); + FGPIO_ERROR("Need to set GPIO direction as OUTPUT first !!!"); return FGPIO_ERR_INVALID_STATE; } @@ -411,9 +417,9 @@ FError FGpioSetOutputValue(FGpioPin *const pin, const FGpioPinVal output) FASSERT(0); } - FGPIO_INFO("output val 0x%x", reg_val); + FGPIO_INFO("Output val 0x%x", reg_val); FGpioWriteRegVal(base_addr, index.port, reg_val); - FGPIO_INFO("output val 0x%x", FGpioReadRegVal(base_addr, index.port)); + FGPIO_INFO("Output val 0x%x", FGpioReadRegVal(base_addr, index.port)); return FGPIO_SUCCESS; } @@ -436,7 +442,7 @@ FGpioPinVal FGpioGetInputValue(FGpioPin *const pin) if (FGPIO_DIR_INPUT != FGpioGetDirection(pin)) { - FGPIO_ERROR("need to set GPIO direction as INPUT first !!!"); + FGPIO_ERROR("Need to set GPIO direction as INPUT first !!!"); return FGPIO_PIN_LOW; } @@ -455,6 +461,6 @@ FGpioPinVal FGpioGetInputValue(FGpioPin *const pin) FASSERT(0); } - FGPIO_INFO("input val: 0x%x", reg_val); + FGPIO_INFO("Input val: 0x%x.", reg_val); return (BIT(index.pin) & reg_val) ? FGPIO_PIN_HIGH : FGPIO_PIN_LOW; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.h b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.h index f41f80aaf2..8d190b7008 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.h +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio.h @@ -19,24 +19,25 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ -#ifndef DRIVERS_FGPIO_H -#define DRIVERS_FGPIO_H +#ifndef FGPIO_H +#define FGPIO_H + +#include "fparameters.h" +#include "ftypes.h" +#include "fassert.h" +#include "ferror_code.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "ftypes.h" -#include "fassert.h" -#include "ferror_code.h" -#include "sdkconfig.h" - /************************** Constant Definitions *****************************/ #define FGPIO_SUCCESS FT_SUCCESS #define FGPIO_ERR_INVALID_PARA FT_MAKE_ERRCODE(ErrModBsp, ErrBspGpio, 0x0) @@ -48,6 +49,8 @@ extern "C" #define FGPIO_VERSION_1 /* 用于FT2000/4和D2000平台的GPIO 0 ~ 1 */ #elif defined(CONFIG_TARGET_E2000) #define FGPIO_VERSION_2 /* 用于E2000平台的GPIO 3 ~ 5 */ +#elif defined(TARDIGRADE) + #else #error "Invalid target board !!!" #endif @@ -72,7 +75,7 @@ typedef enum FGPIO_PIN_5, FGPIO_PIN_6, FGPIO_PIN_7, -#if defined(FGPIO_VERSION_2) /* E2000 GPIO 0 ~ 5 */ +#if defined(FGPIO_VERSION_2) || defined(TARDIGRADE)/* E2000 GPIO 0 ~ 5 */ FGPIO_PIN_8, FGPIO_PIN_9, FGPIO_PIN_10, @@ -130,10 +133,10 @@ typedef struct { u32 instance_id; /* GPIO实例ID */ uintptr base_addr; /* GPIO控制器基地址 */ -#if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */ +#if defined(FGPIO_VERSION_1) || defined(TARDIGRADE) /* FT2000-4, D2000 */ u32 irq_num; /* GPIO控制器中断号 */ #elif defined(FGPIO_VERSION_2) /* E2000 GPIO 0 ~ 5 */ - u32 irq_num[FGPIO_PIN_NUM]; /* GPIO各引脚的中断号 */ + u32 irq_num[FGPIO_PIN_NUM]; /* GPIO各引脚的中断号,如果是控制器中断,则数组所有值一致 */ #endif u32 irq_priority; /* 中断优先级 */ } FGpioConfig; /* GPIO控制器配置 */ diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_g.c b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_g.c index 1c41a6665d..0b05494f9b 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_g.c +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_g.c @@ -19,7 +19,8 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ @@ -43,59 +44,92 @@ #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */ const FGpioConfig fgpio_cfg_tbl[FGPIO_NUM] = { - [FGPIO_ID_0] = + [FGPIO0_ID] = { - .instance_id = FGPIO_ID_0, - .base_addr = FGPIO_0_BASE_ADDR, - .irq_num = FGPIO_0_IRQ_NUM, + .instance_id = FGPIO0_ID, + .base_addr = FGPIO0_BASE_ADDR, + .irq_num = FGPIO0_IRQ_NUM, .irq_priority = 0 }, - [FGPIO_ID_1] = + [FGPIO1_ID] = { - .instance_id = FGPIO_ID_1, - .base_addr = FGPIO_1_BASE_ADDR, - .irq_num = FGPIO_1_IRQ_NUM, + .instance_id = FGPIO1_ID, + .base_addr = FGPIO1_BASE_ADDR, + .irq_num = FGPIO1_IRQ_NUM, .irq_priority = 0 } }; #elif defined(FGPIO_VERSION_2) /* E2000 GPIO 0 ~ 5 */ FGpioConfig fgpio_cfg_tbl[FGPIO_NUM] = { - [FGPIO_ID_0] = + [FGPIO0_ID] = { - .instance_id = FGPIO_ID_0, - .base_addr = FGPIO_0_BASE_ADDR, + .instance_id = FGPIO0_ID, + .base_addr = FGPIO0_BASE_ADDR, .irq_priority = 0 }, - [FGPIO_ID_1] = + [FGPIO1_ID] = { - .instance_id = FGPIO_ID_1, - .base_addr = FGPIO_1_BASE_ADDR, + .instance_id = FGPIO1_ID, + .base_addr = FGPIO1_BASE_ADDR, .irq_priority = 0 }, - [FGPIO_ID_2] = + [FGPIO2_ID] = { - .instance_id = FGPIO_ID_2, - .base_addr = FGPIO_2_BASE_ADDR, + .instance_id = FGPIO2_ID, + .base_addr = FGPIO2_BASE_ADDR, .irq_priority = 0 }, - [FGPIO_ID_3] = + [FGPIO3_ID] = { - .instance_id = FGPIO_ID_3, - .base_addr = FGPIO_3_BASE_ADDR, + .instance_id = FGPIO3_ID, + .base_addr = FGPIO3_BASE_ADDR, .irq_priority = 0 }, - [FGPIO_ID_4] = + [FGPIO4_ID] = { - .instance_id = FGPIO_ID_4, - .base_addr = FGPIO_4_BASE_ADDR, + .instance_id = FGPIO4_ID, + .base_addr = FGPIO4_BASE_ADDR, .irq_priority = 0 }, - [FGPIO_ID_5] = + [FGPIO5_ID] = { - .instance_id = FGPIO_ID_5, - .base_addr = FGPIO_5_BASE_ADDR, + .instance_id = FGPIO5_ID, + .base_addr = FGPIO5_BASE_ADDR, .irq_priority = 0 }, }; +#elif defined(TARDIGRADE) /* TARDIGRADE */ +const FGpioConfig fgpio_cfg_tbl[FGPIO_NUM] = +{ + [FGPIO0_ID] = + { + .instance_id = FGPIO0_ID, + .base_addr = FGPIO0_BASE_ADDR, + .irq_num = FGPIO0_IRQ_NUM, + .irq_priority = 0 + }, + [FGPIO1_ID] = + { + .instance_id = FGPIO1_ID, + .base_addr = FGPIO1_BASE_ADDR, + .irq_num = FGPIO1_IRQ_NUM, + .irq_priority = 0 + }, + [FGPIO2_ID] = + { + .instance_id = FGPIO2_ID, + .base_addr = FGPIO2_BASE_ADDR, + .irq_num = FGPIO2_IRQ_NUM, + .irq_priority = 0 + }, + [FGPIO3_ID] = + { + .instance_id = FGPIO3_ID, + .base_addr = FGPIO3_BASE_ADDR, + .irq_num = FGPIO3_IRQ_NUM, + .irq_priority = 0 + } + +}; #endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_hw.h b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_hw.h index 9acad53bf0..150e04ab8a 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_hw.h @@ -19,22 +19,26 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ -#ifndef DRIVERS_FGPIO_HW_H -#define DRIVERS_FGPIO_HW_H +#ifndef FGPIO_HW_H +#define FGPIO_HW_H + +#include "fio.h" +#include "fkernel.h" + +/***************************** Include Files *********************************/ +#include "fio.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "fio.h" -#include "fkernel.h" - /************************** Constant Definitions *****************************/ /** @name Register Map * @@ -101,6 +105,7 @@ extern "C" /** @name FGPIO_INTMASK_OFFSET Register */ #define FGPIO_INTR_PORTA_MASK(n) BIT(n) /* 1: disable the intr of n-th port in group-a */ +#define FGPIO_INTR_PORTA_MASKALL GENMASK(15, 0) /** @name FGPIO_INTTYPE_LEVEL_OFFSET Register */ @@ -152,9 +157,13 @@ static inline void FGpioWriteReg32(uintptr base_addr, uintptr reg_off, const u32 static inline void FGpioSetBit32(uintptr base_addr, uintptr reg_off, u32 bit) { if (0 == bit) + { FtClearBit32(base_addr + reg_off, bit); + } else if (1 == bit) + { FtSetBit32(base_addr + reg_off, bit); + } } /************************** Function Prototypes ******************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_intr.c b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_intr.c index b453ecdb7e..a4fc9bf2ec 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_intr.c @@ -19,7 +19,8 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ @@ -121,6 +122,7 @@ void FGpioSetInterruptMask(FGpioPin *const pin, boolean enable) FGpioWriteReg32(base_addr, FGPIO_INTMASK_OFFSET, mask_bits); FGpioWriteReg32(base_addr, FGPIO_INTEN_OFFSET, enable_bits); + return; } @@ -183,24 +185,24 @@ void FGpioSetInterruptType(FGpioPin *const pin, const FGpioIrqType type) switch (type) { - case FGPIO_IRQ_TYPE_EDGE_FALLING: - level |= BIT(index.pin); /* 边沿敏感型 */ - polarity &= ~BIT(index.pin); /* 下降沿或低电平 */ - break; - case FGPIO_IRQ_TYPE_EDGE_RISING: - level |= BIT(index.pin); /* 边沿敏感型 */ - polarity |= BIT(index.pin); /* 上升沿或高电平 */ - break; - case FGPIO_IRQ_TYPE_LEVEL_LOW: - level &= ~BIT(index.pin); /* 电平敏感型 */ - polarity &= ~BIT(index.pin); /* 下降沿或低电平 */ - break; - case FGPIO_IRQ_TYPE_LEVEL_HIGH: - level &= ~BIT(index.pin); /* 电平敏感型 */ - polarity |= BIT(index.pin); /* 上升沿或高电平 */ - break; - default: - break; + case FGPIO_IRQ_TYPE_EDGE_FALLING: + level |= BIT(index.pin); /* 边沿敏感型 */ + polarity &= ~BIT(index.pin); /* 下降沿或低电平 */ + break; + case FGPIO_IRQ_TYPE_EDGE_RISING: + level |= BIT(index.pin); /* 边沿敏感型 */ + polarity |= BIT(index.pin); /* 上升沿或高电平 */ + break; + case FGPIO_IRQ_TYPE_LEVEL_LOW: + level &= ~BIT(index.pin); /* 电平敏感型 */ + polarity &= ~BIT(index.pin); /* 下降沿或低电平 */ + break; + case FGPIO_IRQ_TYPE_LEVEL_HIGH: + level &= ~BIT(index.pin); /* 电平敏感型 */ + polarity |= BIT(index.pin); /* 上升沿或高电平 */ + break; + default: + break; } FGpioWriteReg32(base_addr, FGPIO_INTTYPE_LEVEL_OFFSET, level); @@ -228,17 +230,19 @@ void FGpioInterruptHandler(s32 vector, void *param) u32 raw_status = FGpioReadReg32(base_addr, FGPIO_RAW_INTSTATUS_OFFSET); #if defined(FGPIO_VERSION_2) /* E2000 gpio 3 ~ 5 */ - FASSERT_MSG(FGPIO_WITH_PIN_IRQ < instance->config.instance_id, "handle interrupt through pin !!!") + FASSERT_MSG(FGPIO_WITH_PIN_IRQ < instance->config.instance_id, "Handle interrupt through pin !!!") #endif - FGPIO_INFO("status: 0x%x, raw_status: 0x%x", status, raw_status); + FGPIO_INFO("status: 0x%x, raw_status: 0x%x.", status, raw_status); for (loop = FGPIO_PIN_0; loop < FGPIO_PIN_NUM; loop++) { if (status & BIT(loop)) { pin = instance->pins[FGPIO_PORT_A][loop]; if (NULL == pin) + { continue; + } if (pin->irq_cb) { @@ -252,7 +256,7 @@ void FGpioInterruptHandler(s32 vector, void *param) } else { - FGPIO_WARN("no irq handler callback for GPIO-%d-A-%d", + FGPIO_WARN("No irq handler callback for GPIO-%d-A-%d.", instance->config.instance_id, loop); } @@ -283,7 +287,7 @@ void FGpioPinInterruptHandler(s32 vector, void *param) u32 status = FGpioReadReg32(base_addr, FGPIO_INTSTATUS_OFFSET); u32 raw_status = FGpioReadReg32(base_addr, FGPIO_RAW_INTSTATUS_OFFSET); - FGPIO_INFO("status: 0x%x, raw_status: 0x%x", status, raw_status); + FGPIO_INFO("status: 0x%x, raw_status: 0x%x.", status, raw_status); if (pin->irq_cb) { pin->irq_cb(0U, pin->irq_cb_params); @@ -296,7 +300,7 @@ void FGpioPinInterruptHandler(s32 vector, void *param) } else { - FGPIO_WARN("no irq handler callback for GPIO-%d-A-%d", + FGPIO_WARN("No irq handler callback for GPIO-%d-A-%d.", pin->index.ctrl, pin->index.pin); } diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_selftest.c b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_selftest.c index 8cc5ed81e0..b8ebdf2518 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_selftest.c +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_selftest.c @@ -14,11 +14,13 @@ * FilePath: fgpio_selftest.c * Date: 2022-06-17 14:32:12 * LastEditTime: 2022-06-17 14:32:12 - * Description:  This files is for + * Description:  This files is for dumping gpio register info * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ /***************************** Include Files *********************************/ #include "fdebug.h" diff --git a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_sinit.c b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_sinit.c index 2700899002..dff107acc0 100644 --- a/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/pin/fgpio/fgpio_sinit.c @@ -14,12 +14,13 @@ * FilePath: fgpio_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:25:29 - * Description:  This files is for GPIO static variables + * Description:  This files is for GPIO static variables implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022-3-1 init commit + * 1.0 zhugengyu 2022/3/1 init commit + * 2.0 zhugengyu 2022/7/1 support e2000 */ @@ -38,15 +39,15 @@ /************************** Function Prototypes ******************************/ /************************** Variable Definitions *****************************/ -#if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */ - extern const FGpioConfig fgpio_cfg_tbl[FGPIO_NUM]; +#if defined(FGPIO_VERSION_1)|| defined(TARDIGRADE) /* FT2000-4, D2000 */ +extern const FGpioConfig fgpio_cfg_tbl[FGPIO_NUM]; #elif defined(FGPIO_VERSION_2) /* E2000 GPIO 0 ~ 5 */ - extern FGpioConfig fgpio_cfg_tbl[FGPIO_NUM]; +extern FGpioConfig fgpio_cfg_tbl[FGPIO_NUM]; #endif /*****************************************************************************/ -#if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */ +#if defined(FGPIO_VERSION_1) || defined(TARDIGRADE) /* FT2000-4, D2000 */ /** * @name: FGpioLookupConfig * @msg: 获取GPIO控制器的默认配置 @@ -92,15 +93,15 @@ static void FGpioSetIrqNum(u32 instance_id, FGpioConfig *ptr) } else { - if (FGPIO_ID_3 == instance_id) + if (FGPIO3_ID == instance_id) { irq_num = FGPIO_3_IRQ_NUM; } - else if (FGPIO_4_IRQ_NUM == instance_id) + else if (FGPIO4_ID == instance_id) { irq_num = FGPIO_4_IRQ_NUM; } - else if (FGPIO_5_IRQ_NUM == instance_id) + else if (FGPIO5_ID == instance_id) { irq_num = FGPIO_5_IRQ_NUM; } @@ -147,4 +148,5 @@ const FGpioConfig *FGpioLookupConfig(u32 instance_id) return ptr; } + #endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/Kconfig b/bsp/phytium/libraries/standalone/drivers/pwm/Kconfig index 992039d544..5a6185cf4e 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/pwm/Kconfig @@ -3,7 +3,7 @@ menu "FPWM Configuration" bool prompt "Use FPWM" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.c b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.c index 7c1dace19e..4d2022b53c 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.c +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.c @@ -13,13 +13,15 @@ * * FilePath: fpwm.c * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * LastEditTime: 2022-04-15 11:45:05 + * Description:  This file is for the minimum required function implementations for this driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ + #include #include "fkernel.h" #include "ftypes.h" @@ -65,7 +67,7 @@ FError FPwmReset(FPwmCtrl *pctrl, u32 channel) if (0 >= timeout) { - FPWM_ERROR("timeout when wait pwm reset complete"); + FPWM_ERROR("Time out while waiting for pwm reset to complete"); return FPWM_ERR_TIMEOUT; } return FPWM_SUCCESS; @@ -136,16 +138,16 @@ static void FPwmTimCtrlModeSet(FPwmCtrl *pctrl, u32 channel, FPwmTimCtrlMode mod switch (mode) { - /* modulo */ - case FPWM_MODULO: - reg_val &= (~FPWM_TIM_CTRL_MODE_UD); - break; - /* up-and-down */ - case FPWM_UP_DOWN: - reg_val |= FPWM_TIM_CTRL_MODE_UD; - break; - default: - break; + /* modulo */ + case FPWM_MODULO: + reg_val &= (~FPWM_TIM_CTRL_MODE_UD); + break; + /* up-and-down */ + case FPWM_UP_DOWN: + reg_val |= FPWM_TIM_CTRL_MODE_UD; + break; + default: + break; } FPWM_WRITE_REG32(base_addr, FPWM_TIM_CTRL_OFFSET, reg_val); @@ -251,16 +253,16 @@ static void FPwmDutySourceSet(FPwmCtrl *pctrl, u32 channel, FPwmDutySourceMode d reg_val = FPWM_READ_REG32(base_addr, FPWM_CTRL_OFFSET); switch (duty_source) { - /* duty from PWM_CCR */ - case FPWM_DUTY_CCR: - reg_val &= (~FPWM_CTRL_DUTY_SOURCE_FIFO); - break; - /* from FIFO */ - case FPWM_DUTY_FIFO: - reg_val |= FPWM_CTRL_DUTY_SOURCE_FIFO; - break; - default: - break; + /* duty from PWM_CCR */ + case FPWM_DUTY_CCR: + reg_val &= (~FPWM_CTRL_DUTY_SOURCE_FIFO); + break; + /* from FIFO */ + case FPWM_DUTY_FIFO: + reg_val |= FPWM_CTRL_DUTY_SOURCE_FIFO; + break; + default: + break; } FPWM_WRITE_REG32(base_addr, FPWM_CTRL_OFFSET, reg_val); @@ -289,7 +291,7 @@ FError FPwmPulseSet(FPwmCtrl *pctrl, u32 channel, u16 pwm_ccr) pwm_period_ccr = (u16)FPWM_READ_REG32(base_addr, FPWM_PERIOD_OFFSET); if (pwm_ccr > pwm_period_ccr) { - FPWM_ERROR("pwm ccr is bigger than period"); + FPWM_ERROR("The pwm ccr is larger than the period"); return FPWM_ERR_INVAL_PARM; } @@ -302,7 +304,7 @@ FError FPwmPulseSet(FPwmCtrl *pctrl, u32 channel, u16 pwm_ccr) state = FPWM_READ_REG32(base_addr, FPWM_STATE_OFFSET); if (state & FPWM_STATE_FIFO_FULL) { - FPWM_ERROR("pwm state fifo full"); + FPWM_ERROR("The fifo of the pwm is full"); return FPWM_ERR_CMD_FAILED; } } @@ -386,7 +388,7 @@ static FError FPwmDbReset(FPwmCtrl *pctrl) if (0 >= timeout) { - FPWM_ERROR("timeout when wait pwm db reset complete"); + FPWM_ERROR("Time out while waiting for pwm db reset to complete"); return FPWM_ERR_TIMEOUT; } return FPWM_SUCCESS; @@ -476,14 +478,14 @@ static void FPwmDbInModeSet(FPwmCtrl *pctrl, FPwmDbInMode db_in_mode) reg_val = FPWM_READ_REG32(base_addr, FPWM_DB_CTRL_OFFSET); switch (db_in_mode) { - case FPWM_DB_IN_MODE_PWM0: - reg_val &= (~FPWM_DB_CTRL_IN_MODE); - break; - case FPWM_DB_IN_MODE_PWM1: - reg_val |= FPWM_DB_CTRL_IN_MODE; - break; - default: - break; + case FPWM_DB_IN_MODE_PWM0: + reg_val &= (~FPWM_DB_CTRL_IN_MODE); + break; + case FPWM_DB_IN_MODE_PWM1: + reg_val |= FPWM_DB_CTRL_IN_MODE; + break; + default: + break; } FPWM_WRITE_REG32(base_addr, FPWM_DB_CTRL_OFFSET, reg_val); @@ -581,7 +583,7 @@ FError FPwmDbVariableSet(FPwmCtrl *pctrl, FPwmDbVariableConfig *db_cfg_p) ret = FPwmDbReset(pctrl); if (ret != FPWM_SUCCESS) { - FPWM_ERROR("FPwmDbVariableSet FPwmDbReset failed"); + FPWM_ERROR("%s ,The FPwmDbReset call failed",__func__); return FPWM_ERR_CMD_FAILED; } @@ -592,7 +594,7 @@ FError FPwmDbVariableSet(FPwmCtrl *pctrl, FPwmDbVariableConfig *db_cfg_p) ret = FPwmDbPolaritySet(pctrl, db_cfg_p->db_polarity_sel); if (ret != FPWM_SUCCESS) { - FPWM_ERROR("FPwmDbVariableSet FPwmDbPolaritySet failed"); + FPWM_ERROR("%s ,The FPwmDbPolaritySet call failed",__func__); return FPWM_ERR_CMD_FAILED; } @@ -654,14 +656,15 @@ FError FPwmVariableSet(FPwmCtrl *pctrl, u32 channel, FPwmVariableConfig *pwm_cfg FASSERT(pwm_cfg_p != NULL); FError ret = FPWM_SUCCESS; +#if defined(FLSD_CONFIG_BASE) /* enable lsd pwm syn */ FPwmLsdEnable(FLSD_CONFIG_BASE, pctrl->config.instance_id); - +#endif /* bit[0]:set pwm_tim_ctrl SW_RST */ ret = FPwmReset(pctrl, channel); if (ret != FPWM_SUCCESS) { - FPWM_ERROR("FPwmVariableSet FPwmReset failed"); + FPWM_ERROR("%s ,FPwmReset call failed",__func__); return FPWM_ERR_CMD_FAILED; } @@ -697,7 +700,7 @@ FError FPwmVariableSet(FPwmCtrl *pctrl, u32 channel, FPwmVariableConfig *pwm_cfg ret = FPwmPulseSet(pctrl, channel, pwm_cfg_p->pwm_pulse); if (ret != FPWM_SUCCESS) { - FPWM_ERROR("FPwmVariableSet FPwmPulseSet failed"); + FPWM_ERROR("%s , FPwmPulseSet failed",__func__); return FPWM_ERR_CMD_FAILED; } @@ -787,22 +790,45 @@ FError FPwmCfgInitialize(FPwmCtrl *pctrl, const FPwmConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == pctrl->is_ready) { - FPWM_WARN("device is already initialized!!!"); + FPWM_WARN("The device has been initialized!!!"); } /*Set default values and configuration data */ FPwmDeInitialize(pctrl); pctrl->config = *input_config_p; - +#if defined(CONFIG_TARGET_E2000) ret = FPwmDbReset(pctrl); if (ret != FPWM_SUCCESS) { - FPWM_ERROR("FPwmDbVariableSet FPwmDbReset failed"); + FPWM_ERROR("%s ,The FPwmDbReset call failed"); return FPWM_ERR_CMD_FAILED; } - +#endif pctrl->is_ready = FT_COMPONENT_IS_READY; return ret; } + +/** + * @name: FPwmGpioSet + * @msg: Control gpio output + * @param {FPwmCtrl} *pctrl, instance of FPWM controller + * @param {u32} channel, pwm module's channel, 0/1 + * @param {u32} output, set high or low level, 0-low, 1-high + * @return void + */ +void FPwmGpioSet(FPwmCtrl *pctrl, u32 channel, u32 output) +{ + FASSERT(pctrl != NULL); + u32 reg_val = 0; + uintptr base_addr = pctrl->config.pwm_base_addr + FPWM_N(channel); + + reg_val = FPWM_READ_REG32(base_addr, FPWM_CCR_OFFSET); + if(output) + reg_val |= FPWM_CCR_GPIO; + else + reg_val &= (~FPWM_CCR_GPIO); + FPWM_WRITE_REG32(base_addr, FPWM_CCR_OFFSET, reg_val); + +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.h b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.h index 80e62ae896..7a7ca6e9c7 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.h +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm.h @@ -13,21 +13,17 @@ * * FilePath: fpwm.h * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * LastEditTime: 2022-04-15 11:45:05 + * Description: This file is for detailed description of the device configuration and driver. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ -#ifndef BSP_DRIVERS_FPWM_H -#define BSP_DRIVERS_FPWM_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FPWM_H +#define FPWM_H #include "ftypes.h" #include "fdebug.h" @@ -36,6 +32,11 @@ extern "C" #include "fassert.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define FPWM_SUCCESS FT_SUCCESS #define FPWM_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspPwm, 1) #define FPWM_ERR_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspPwm, 2) @@ -181,7 +182,7 @@ void FPwmIntrHandler(s32 vector, void *args); void FPwmRegisterInterruptHandler(FPwmCtrl *instance_p, FPwmIntrEventType event_type, FPwmIntrEventHandler handler, void *param); /* get pwm configs by id */ -const FPwmConfig *FPwmLookupConfig(FPwmInstance instance_id); +const FPwmConfig *FPwmLookupConfig(u32 instance_id); /* DeInitialization function for the device instance */ void FPwmDeInitialize(FPwmCtrl *pctrl); @@ -213,6 +214,9 @@ void FPwmEnable(FPwmCtrl *pctrl, u32 channel); /* dump some pwm registers value */ void FPwmDump(uintptr base_addr); +/* control gpio output */ +void FPwmGpioSet(FPwmCtrl *pctrl, u32 channel, u32 output); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_g.c b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_g.c index b1bcc554e7..81ba3b2ef3 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_g.c +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_g.c @@ -13,117 +13,138 @@ * * FilePath: fpwm_g.c * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * LastEditTime: 2022-04-16 11:45:05 + * Description:  This file is for pwm static configuration implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/16 init commit */ #include "fparameters.h" #include "fpwm.h" #include "fpwm_hw.h" +#include "sdkconfig.h" +#if defined(CONFIG_TARGET_E2000) /* default configs of pwm ctrl */ -const FPwmConfig FPwmConfigTbl[FPWM_INSTANCE_NUM] = +const FPwmConfig FPwmConfigTbl[FPWM_NUM] = { - [FPWM_INSTANCE_0] = + [FPWM0_ID] = { - .instance_id = FPWM_INSTANCE_0, + .instance_id = FPWM0_ID, .db_base_addr = FPWM0_BASE_ADR, .pwm_base_addr = FPWM0_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM0_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM1_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM0_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM1_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL0", }, - [FPWM_INSTANCE_1] = + [FPWM1_ID] = { - .instance_id = FPWM_INSTANCE_1, + .instance_id = FPWM1_ID, .db_base_addr = FPWM1_BASE_ADR, .pwm_base_addr = FPWM1_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM2_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM3_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM2_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM3_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL1", }, - [FPWM_INSTANCE_2] = + [FPWM2_ID] = { - .instance_id = FPWM_INSTANCE_2, + .instance_id = FPWM2_ID, .db_base_addr = FPWM2_BASE_ADR, .pwm_base_addr = FPWM2_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM4_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM5_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM4_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM5_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL2", }, - [FPWM_INSTANCE_3] = + [FPWM3_ID] = { - .instance_id = FPWM_INSTANCE_3, + .instance_id = FPWM3_ID, .db_base_addr = FPWM3_BASE_ADR, .pwm_base_addr = FPWM3_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM6_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM7_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM6_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM7_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL3", }, - [FPWM_INSTANCE_4] = + [FPWM4_ID] = { - .instance_id = FPWM_INSTANCE_4, + .instance_id = FPWM4_ID, .db_base_addr = FPWM4_BASE_ADR, .pwm_base_addr = FPWM4_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM8_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM9_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM8_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM9_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL4", }, - [FPWM_INSTANCE_5] = + [FPWM5_ID] = { - .instance_id = FPWM_INSTANCE_5, + .instance_id = FPWM5_ID, .db_base_addr = FPWM5_BASE_ADR, .pwm_base_addr = FPWM5_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM10_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM11_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM10_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM11_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL5", }, - [FPWM_INSTANCE_6] = + [FPWM6_ID] = { - .instance_id = FPWM_INSTANCE_6, + .instance_id = FPWM6_ID, .db_base_addr = FPWM6_BASE_ADR, .pwm_base_addr = FPWM6_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM12_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM13_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM12_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM13_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL6", }, - [FPWM_INSTANCE_7] = + [FPWM7_ID] = { - .instance_id = FPWM_INSTANCE_7, + .instance_id = FPWM7_ID, .db_base_addr = FPWM7_BASE_ADR, .pwm_base_addr = FPWM7_BASE_ADR + FPWM_OFFSET, - .base_clk = FPWM_CLK, - .irq_num[FPWM_CHANNEL_0] = FPWM14_INTR_IRQ, - .irq_num[FPWM_CHANNEL_1] = FPWM15_INTR_IRQ, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM14_IRQ_NUM, + .irq_num[FPWM_CHANNEL_1] = FPWM15_IRQ_NUM, .irq_prority[FPWM_CHANNEL_0] = 0, .irq_prority[FPWM_CHANNEL_1] = 0, .instance_name = "PWM_CTRL7", }, -}; \ No newline at end of file +}; + +#elif defined(TARDIGRADE) +/* default configs of pwm ctrl */ +const FPwmConfig FPwmConfigTbl[FPWM_NUM] = +{ + [FPWM0_ID] = + { + .instance_id = FPWM0_ID, + .pwm_base_addr = FPWM0_BASE_ADR, + .base_clk = FPWM_CLK_FREQ_HZ, + .irq_num[FPWM_CHANNEL_0] = FPWM0_IRQ_NUM, + .irq_prority[FPWM_CHANNEL_0] = 0, + .instance_name = "PWM_CTRL0", + }, + +}; + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.c b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.c index 33bce2b6c1..4a4449fe18 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.c @@ -14,11 +14,12 @@ * FilePath: fpwm_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * Description:  This file is for pwm register implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ #include @@ -35,7 +36,7 @@ */ void FPwmLsdEnable(uintptr lsd_addr, u8 pwm_id) { - FASSERT(pwm_id < FPWM_INSTANCE_NUM); + FASSERT(pwm_id < FPWM_NUM); u32 reg_val = 0; reg_val = FPWM_READ_REG32(lsd_addr, FLSD_MIO_PWM_SYN_OFFSET); @@ -54,7 +55,7 @@ void FPwmLsdEnable(uintptr lsd_addr, u8 pwm_id) */ void FPwmLsdDisable(uintptr lsd_addr, u8 pwm_id) { - FASSERT(pwm_id < FPWM_INSTANCE_NUM); + FASSERT(pwm_id < FPWM_NUM); u32 reg_val = 0; reg_val = FPWM_READ_REG32(lsd_addr, FLSD_MIO_PWM_SYN_OFFSET); @@ -94,10 +95,10 @@ void FPwmDump(uintptr base_addr) printf("Off[0x%x]: FPWM_PERIOD_OFFSET = 0x%08x\r\n", pwm_base_addr + FPWM_PERIOD_OFFSET, FPWM_READ_REG32(pwm_base_addr, FPWM_PERIOD_OFFSET)); printf("Off[0x%x]: FPWM_CTRL_OFFSET = 0x%08x\r\n", pwm_base_addr + FPWM_CTRL_OFFSET, FPWM_READ_REG32(pwm_base_addr, FPWM_CTRL_OFFSET)); printf("Off[0x%x]: FPWM_CCR_OFFSET = 0x%08x\r\n", pwm_base_addr + FPWM_CCR_OFFSET, FPWM_READ_REG32(pwm_base_addr, FPWM_CCR_OFFSET)); - - + +#if defined(FLSD_CONFIG_BASE) printf("Off[0x%x]: FPWM_LSD_OFFSET = 0x%08x\r\n", FLSD_CONFIG_BASE + FLSD_MIO_PWM_SYN_OFFSET, FPWM_READ_REG32(FLSD_CONFIG_BASE, FLSD_MIO_PWM_SYN_OFFSET)); - +#endif printf("\r\n"); - + } diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.h b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.h index c1efe992bd..7050ba4a64 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_hw.h @@ -14,28 +14,29 @@ * FilePath: fpwm_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * Description:  This file is for pwm register definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ -#ifndef BSP_DRIVERS_FPWM_HW_H -#define BSP_DRIVERS_FPWM_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FPWM_HW_H +#define FPWM_HW_H #include "fkernel.h" #include "ftypes.h" #include "fio.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* pwm register definitions */ -#define FPWM_BASE_ADR(n) ((FPWM_CONTROL_BASE)+(n<<12)) /* 0<=n<=7 */ +#define FPWM_BASE_ADR(n) ((FPWM_BASE_ADDR)+(n<<12)) /* 0<=n<=7 */ #define FPWM0_BASE_ADR FPWM_BASE_ADR(0) /* PWM 0 base address */ #define FPWM1_BASE_ADR FPWM_BASE_ADR(1) /* PWM 1 base address */ @@ -113,6 +114,7 @@ extern "C" /* pwm_ccr field */ #define FPWM_CCR_MASK GENMASK(15, 0) +#define FPWM_CCR_GPIO BIT(16) /* pwm lsd cfg, lsd pwm sync control */ #define FLSD_MIO_PWM_SYN_OFFSET 0x20 diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_intr.c b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_intr.c index 2439328f5f..49773c9cd3 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_intr.c @@ -13,16 +13,17 @@ * * FilePath: fpwm_intr.c * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * LastEditTime: 2022-04-25 11:45:05 + * Description:  This file is for pwm interrupt handler implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ + #include "fparameters.h" #include "fassert.h" -#include "finterrupt.h" #include "fpwm.h" #include "fpwm_hw.h" @@ -78,11 +79,15 @@ void FPwmIntrHandler(s32 vector, void *args) status = FPWM_READ_REG32(pwm_base_addr, FPWM_CTRL_OFFSET); if (!(status & (FPWM_CTRL_INTR_COUNTER_ENABLE | FPWM_CTRL_INTR_FIFO_EMPTY_ENABLE))) + { continue; + } status = FPWM_READ_REG32(pwm_base_addr, FPWM_STATE_OFFSET); if (0 == status) + { continue; + } /* Check for the type of error interrupt and Processing it */ if (status & FPWM_STATE_OVFIF_COUNTER) diff --git a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_sinit.c b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_sinit.c index a4d13ec00b..f7a9487c23 100644 --- a/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/pwm/fpwm/fpwm_sinit.c @@ -13,12 +13,13 @@ * * FilePath: fpwm_sinit.c * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * LastEditTime: 2022-04-25 11:45:05 + * Description:  This file is for pwm static variables implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ @@ -28,7 +29,7 @@ #include "fparameters.h" #include "fassert.h" -extern FPwmConfig FPwmConfigTbl[FPWM_INSTANCE_NUM]; +extern FPwmConfig FPwmConfigTbl[FPWM_NUM]; /************************** Constant Definitions *****************************/ @@ -46,14 +47,14 @@ extern FPwmConfig FPwmConfigTbl[FPWM_INSTANCE_NUM]; * @return {*} * @param {u32} instanceId, id of pwm ctrl */ -const FPwmConfig *FPwmLookupConfig(FPwmInstance instance_id) +const FPwmConfig *FPwmLookupConfig(u32 instance_id) { const FPwmConfig *pconfig = NULL; - FASSERT(instance_id < FPWM_INSTANCE_NUM); + FASSERT(instance_id < FPWM_NUM); u32 index = 0; - for (index = 0; index < (u32)FPWM_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FPWM_NUM; index++) { if (FPwmConfigTbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/Kconfig b/bsp/phytium/libraries/standalone/drivers/qspi/Kconfig index 7e7a9e54c2..a16b375482 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/qspi/Kconfig @@ -2,7 +2,7 @@ menu "Qspi Configuration" config USE_FQSPI bool prompt "Use FQSPI" - default n - + default n + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.c b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.c index fc42e8535d..f28004b792 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.c +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.c @@ -14,13 +14,14 @@ * FilePath: fqspi.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-03-28 09:00:41 - * Description:  This files is for + * Description:  This files is for the qspi specific functions implementations * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct - * 1.2 wangxiaodong 2022.3.27 re-construct + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions + * 1.2 zhangyan 2022/12/7 improve functions */ #include @@ -29,6 +30,7 @@ #include "fqspi.h" #include "fqspi_hw.h" #include "fsleep.h" +#include "fqspi_flash.h" #define FQSPI_DEBUG_TAG "FQSPI" #define FQSPI_ERROR(format, ...) FT_DEBUG_PRINT_E(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) @@ -57,7 +59,7 @@ FError FQspiCfgInitialize(FQspiCtrl *pctrl, const FQspiConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == pctrl->is_ready) { - FQSPI_WARN("device is already initialized!!!"); + FQSPI_WARN("Device is already initialized!!!"); } /*Set default values and configuration data */ @@ -101,30 +103,30 @@ void FQspiSetCapacityAndNum(FQspiCtrl *pctrl) switch (config_p->capacity) { - case FQSPI_FLASH_CAP_4MB: - pctrl->flash_size = SZ_4M; - break; - case FQSPI_FLASH_CAP_8MB: - pctrl->flash_size = SZ_8M; - break; - case FQSPI_FLASH_CAP_16MB: - pctrl->flash_size = SZ_16M; - break; - case FQSPI_FLASH_CAP_32MB: - pctrl->flash_size = SZ_32M; - break; - case FQSPI_FLASH_CAP_64MB: - pctrl->flash_size = SZ_64M; - break; - case FQSPI_FLASH_CAP_128MB: - pctrl->flash_size = SZ_128M; - break; - case FQSPI_FLASH_CAP_256MB: - pctrl->flash_size = SZ_256M; - break; - default: - pctrl->flash_size = SZ_4M; - break; + case FQSPI_FLASH_CAP_4MB: + pctrl->flash_size = SZ_4M; + break; + case FQSPI_FLASH_CAP_8MB: + pctrl->flash_size = SZ_8M; + break; + case FQSPI_FLASH_CAP_16MB: + pctrl->flash_size = SZ_16M; + break; + case FQSPI_FLASH_CAP_32MB: + pctrl->flash_size = SZ_32M; + break; + case FQSPI_FLASH_CAP_64MB: + pctrl->flash_size = SZ_64M; + break; + case FQSPI_FLASH_CAP_128MB: + pctrl->flash_size = SZ_128M; + break; + case FQSPI_FLASH_CAP_256MB: + pctrl->flash_size = SZ_256M; + break; + default: + pctrl->flash_size = SZ_4M; + break; } /* Write flash capacity and numbers information to qspi Capacity register */ @@ -133,7 +135,7 @@ void FQspiSetCapacityAndNum(FQspiCtrl *pctrl) /*write value to flash capacity register 0x00 */ FQSPI_WRITE_REG32(base_addr, FQSPI_REG_CAP_OFFSET, reg_val); - + FQSPI_INFO("The flash chip size is %ld bytes.\n", pctrl->flash_size); } @@ -184,7 +186,6 @@ FError FQspiRdCfgConfig(FQspiCtrl *pctrl) cmd_reg |= FQSPI_RD_CFG_SCK_SEL(rd_config.rd_sck_sel); FQSPI_WRITE_REG32(base_addr, FQSPI_REG_RD_CFG_OFFSET, cmd_reg); - return ret; } @@ -278,10 +279,10 @@ FError FQspiCommandPortConfig(FQspiCtrl *pctrl) * @name: FQspiChannelSet * @msg: config qspi cs num * @param {FQspiCtrl} *pctrl, instance of FQSPI controller - * @param {FQspiChipCS} channel, cs number + * @param {u32} channel, cs number * @return */ -void FQspiChannelSet(FQspiCtrl *pctrl, FQspiChipCS channel) +void FQspiChannelSet(FQspiCtrl *pctrl, u32 channel) { FASSERT(pctrl); FASSERT(channel < FQSPI_CS_NUM); @@ -310,3 +311,5 @@ void FQspiCsTimingSet(FQspiCtrl *pctrl, FQspiCsTimingCfgDef *cs_timing_cfg) FQSPI_WRITE_REG32(base_addr, FQSPI_REG_CS_TIMING_SET_OFFSET, cmd_reg); } + + diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.h b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.h index 407187ec26..f8e259de95 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.h +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi.h @@ -14,12 +14,14 @@ * FilePath: fqspi.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:00:55 - * Description:  This files is for + * Description:  This files is for the qspi functions related definitions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions + * 1.2 zhangyan 2022/12/7 improve functions */ #ifndef BSP_DRIVERS_FQSPI_H @@ -226,7 +228,7 @@ FError FQspiRdCfgConfig(FQspiCtrl *pctrl); FError FQspiWrCfgConfig(FQspiCtrl *pctrl); /* qspi cs number set */ -void FQspiChannelSet(FQspiCtrl *pctrl, FQspiChipCS channel); +void FQspiChannelSet(FQspiCtrl *pctrl, u32 channel); /* qspi cs timing set */ void FQspiCsTimingSet(FQspiCtrl *pctrl, FQspiCsTimingCfgDef *cs_timing_cfg); diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.c b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.c index a3e5fbf0c8..5e7e5d876c 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.c +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.c @@ -14,11 +14,13 @@ * FilePath: fqspi_flash.c * Date: 2022-07-12 15:42:55 * LastEditTime: 2022-07-12 15:42:56 - * Description: This file is for + * Description: This file is for S25FS256, GD25Q256, GD25Q64 norflash program functions * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions */ #include @@ -63,38 +65,57 @@ FError FQspiFlashDetect(FQspiCtrl *pctrl) FError ret = FQSPI_SUCCESS; u8 flash_id[3] = {0}; u8 i = 0; - - /* read id to flash_id */ - ret = FQspiFlashSpecialInstruction(pctrl, FQSPI_FLASH_CMD_RDID, flash_id, sizeof(flash_id)); - if (FQSPI_SUCCESS != ret) + u32 index; + u32 cs_number = 0; + u32 min_detected_cs = FQSPI_CS_NUM ; + + for (index = 0; index < FQSPI_CS_NUM ; index++) { - FQSPI_ERROR("read flash id failed, ret 0x%x\r\n", ret); - return ret; - } - - FQSPI_INFO("flash id = 0x%x, 0x%x, 0x%x\r\n", flash_id[0], flash_id[1], flash_id[2]); - - for (i = 0; i < sizeof(flash_info_table) / sizeof(FQspiFlashInfo); i++) - { - if ((flash_info_table[i].mf_id == flash_id[0]) && (flash_info_table[i].type_id == flash_id[1]) - && (flash_info_table[i].capacity_id == flash_id[2])) + /* read id to flash_id */ + pctrl->config.channel = index; + ret = FQspiFlashSpecialInstruction(pctrl, FQSPI_FLASH_CMD_RDID, flash_id, sizeof(flash_id)); + if (FQSPI_SUCCESS != ret) { - pctrl->mf_id = flash_info_table[i].mf_id; - pctrl->config.capacity = flash_info_table[i].capacity; - break; + FQSPI_ERROR("Read flash id failed, ret 0x%x\r\n", ret); + return ret; } + + if (flash_id[0] != 0xff) + { + FQSPI_INFO("CSN%d flash id = 0x%x, 0x%x, 0x%x\r\n", index, flash_id[0], flash_id[1], flash_id[2]); + } + else + { + FQSPI_ERROR("The Detected CSN%d flash is not matched", index); + } + + for (i = 0; i < sizeof(flash_info_table) / sizeof(FQspiFlashInfo); i++) + { + if ((flash_info_table[i].mf_id == flash_id[0]) && (flash_info_table[i].type_id == flash_id[1]) + && (flash_info_table[i].capacity_id == flash_id[2])) + { + pctrl->mf_id = flash_info_table[i].mf_id; + pctrl->config.capacity = flash_info_table[i].capacity; + cs_number++; + /*get the min detected flash channel*/ + min_detected_cs = (min_detected_cs > index)?index:min_detected_cs ; + FQSPI_INFO("CSN%d Find a %s flash chip.\n", index, flash_info_table[i].name); + break; + } + } + /*The default channel is the min detected flash*/ + pctrl->config.channel = min_detected_cs; + + if (i == sizeof(flash_info_table) / sizeof(FQspiFlashInfo) && flash_id[0] != 0xff) + { + FQSPI_ERROR("The Detected CSN%d flash not detected, id = 0x%x, 0x%x, 0x%x\r\n", index, flash_id[0], flash_id[1], flash_id[2]); + } + } - if (i == sizeof(flash_info_table) / sizeof(FQspiFlashInfo)) - { - FQSPI_ERROR("The Detected flash is not matched, id = 0x%x, 0x%x, 0x%x\r\n", flash_id[0], flash_id[1], flash_id[2]); - return FQSPI_NOT_SUPPORT; - } - + pctrl->config.dev_num = cs_number - 1; /* set flash num and flash capacity */ FQspiSetCapacityAndNum(pctrl); - FQSPI_INFO("Find a %s flash chip. Size is %ld bytes.\n", flash_info_table[i].name, pctrl->flash_size); - return ret; } @@ -111,14 +132,14 @@ static FError FQspiFlashReset(FQspiCtrl *pctrl) ret = FQspiFlashWriteReg(pctrl, FQSPI_CMD_ENABLE_RESET, NULL, 0); if (FQSPI_SUCCESS != ret) { - FQSPI_ERROR("failed to enable reset, test result 0x%x\r\n", ret); + FQSPI_ERROR("Failed to enable reset, test result 0x%x\r\n", ret); return ret; } ret = FQspiFlashWriteReg(pctrl, FQSPI_CMD_RESET, NULL, 0); if (FQSPI_SUCCESS != ret) { - FQSPI_ERROR("failed to reset, test result 0x%x\r\n", ret); + FQSPI_ERROR("Failed to reset, test result 0x%x\r\n", ret); return ret; } @@ -407,117 +428,138 @@ FError FQspiFlashReadDataConfig(FQspiCtrl *pctrl, u8 command) switch (command) { - case FQSPI_FLASH_CMD_READ: - FQspiFlashReset(pctrl); - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; - break; + case FQSPI_FLASH_CMD_READ: + FQspiFlashReset(pctrl); + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; + break; - case FQSPI_FLASH_CMD_4READ: - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; - break; + case FQSPI_FLASH_CMD_4READ: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; + break; - case FQSPI_FLASH_CMD_FAST_READ: - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; - pctrl->rd_cfg.dummy = 8; - pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; - break; + case FQSPI_FLASH_CMD_FAST_READ: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; + pctrl->rd_cfg.dummy = 8; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + break; - case FQSPI_FLASH_CMD_4FAST_READ: - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; - pctrl->rd_cfg.dummy = 8; - pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; - break; + case FQSPI_FLASH_CMD_4FAST_READ: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_1; + pctrl->rd_cfg.dummy = 8; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + break; - case FQSPI_FLASH_CMD_DUAL_READ: - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_2_2; - pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + case FQSPI_FLASH_CMD_DOR: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_2; + pctrl->rd_cfg.dummy = 8; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + break; - if (pctrl->mf_id == FQSPI_FLASH_MF_ID_CYPRESS) - { + case FQSPI_FLASH_CMD_QOR: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_1_4; + pctrl->rd_cfg.dummy = 8; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + break; + + case FQSPI_FLASH_CMD_QWFR: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_4_4; + pctrl->rd_cfg.dummy = 2; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + break; + + case FQSPI_FLASH_CMD_DUAL_READ: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_2_2; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + + if (pctrl->mf_id == FQSPI_FLASH_MF_ID_CYPRESS) + { + pctrl->rd_cfg.mode_byte = 0x1; + pctrl->rd_cfg.cmd_sign = FQSPI_QUAD_READ_MODE_CMD; + pctrl->rd_cfg.dummy = 8; + } + else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_GIGADEVICE) + { + pctrl->rd_cfg.dummy = 4; + } + else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_BOYA) + { + pctrl->rd_cfg.dummy = 4; + } + break; + + case FQSPI_FLASH_CMD_QIOR: + /* set SR1V and CR1V */ + FQspiFlashEnableWrite(pctrl); + + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_4_4; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; + + if (pctrl->mf_id == FQSPI_FLASH_MF_ID_CYPRESS) + { + pctrl->rd_cfg.dummy = 10; + /* use wrr write config register 1 */ + ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, wrr_buf, sizeof(wrr_buf)); + if (FQSPI_SUCCESS != ret) + { + FQSPI_ERROR("Failed to write cmd wrr, test result 0x%x", ret); + return 0; + } + } + else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_GIGADEVICE) + { + pctrl->rd_cfg.dummy = 6; + /* use wrr write config register 1 */ + ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, wrr_buf, sizeof(wrr_buf)); + if (FQSPI_SUCCESS != ret) + { + FQSPI_ERROR("Failed to write cmd wrr, test result 0x%x", ret); + return 0; + } + } + else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_BOYA) + { + pctrl->rd_cfg.dummy = 6; + ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRITE_SR2, &wrr_buf[1], 1); + if (FQSPI_SUCCESS != ret) + { + FQSPI_ERROR("Failed to write cmd wrr, test result 0x%x", ret); + return 0; + } + } + + break; + + case FQSPI_FLASH_CMD_4QIOR: + pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; + pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_4_4; pctrl->rd_cfg.mode_byte = 0x1; pctrl->rd_cfg.cmd_sign = FQSPI_QUAD_READ_MODE_CMD; + pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; pctrl->rd_cfg.dummy = 8; - } - else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_GIGADEVICE) - { - pctrl->rd_cfg.dummy = 4; - } - else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_BOYA) - { - pctrl->rd_cfg.dummy = 4; - } - break; - case FQSPI_FLASH_CMD_QIOR: - /* set SR1V and CR1V */ - FQspiFlashEnableWrite(pctrl); - - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_3; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_4_4; - pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; - - if (pctrl->mf_id == FQSPI_FLASH_MF_ID_CYPRESS) - { - pctrl->rd_cfg.dummy = 10; + /* set SR1V and CR1V */ + FQspiFlashEnableWrite(pctrl); /* use wrr write config register 1 */ ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, wrr_buf, sizeof(wrr_buf)); if (FQSPI_SUCCESS != ret) { - FQSPI_ERROR("failed to write cmd wrr, test result 0x%x", ret); - return 0; + FQSPI_ERROR("Failed to write cmd wrr, test result 0x%x\r\n", ret); + return ret; } - } - else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_GIGADEVICE) - { - pctrl->rd_cfg.dummy = 6; - /* use wrr write config register 1 */ - ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, wrr_buf, sizeof(wrr_buf)); - if (FQSPI_SUCCESS != ret) - { - FQSPI_ERROR("failed to write cmd wrr, test result 0x%x", ret); - return 0; - } - } - else if (pctrl->mf_id == FQSPI_FLASH_MF_ID_BOYA) - { - pctrl->rd_cfg.dummy = 6; - ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRITE_SR2, &wrr_buf[1], 1); - if (FQSPI_SUCCESS != ret) - { - FQSPI_ERROR("failed to write cmd wrr, test result 0x%x", ret); - return 0; - } - } + break; - break; - - case FQSPI_FLASH_CMD_4QIOR: - pctrl->rd_cfg.rd_addr_sel = FQSPI_ADDR_SEL_4; - pctrl->rd_cfg.rd_transfer = FQSPI_TRANSFER_1_4_4; - pctrl->rd_cfg.mode_byte = 0x1; - pctrl->rd_cfg.cmd_sign = FQSPI_QUAD_READ_MODE_CMD; - pctrl->rd_cfg.rd_latency = FQSPI_CMD_LATENCY_ENABLE; - pctrl->rd_cfg.dummy = 8; - - /* set SR1V and CR1V */ - FQspiFlashEnableWrite(pctrl); - /* use wrr write config register 1 */ - ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, wrr_buf, sizeof(wrr_buf)); - if (FQSPI_SUCCESS != ret) - { - FQSPI_ERROR("failed to write cmd wrr, test result 0x%x\r\n", ret); - return ret; - } - break; - - default: - return FQSPI_INVAL_PARAM; - break; + default: + return FQSPI_INVAL_PARAM; + break; } ret = FQspiRdCfgConfig(pctrl); @@ -572,18 +614,18 @@ FError FQspiFlashWriteData(FQspiCtrl *pctrl, u8 command, u32 chip_addr, const u8 /* set addr_sel region, FQSPI_ADDR_SEL_3 or FQSPI_ADDR_SEL_4 */ switch (command) { - case FQSPI_FLASH_CMD_PP: - case FQSPI_FLASH_CMD_QPP: - pctrl->wr_cfg.wr_addr_sel = FQSPI_ADDR_SEL_3; - break; - case FQSPI_FLASH_CMD_4PP: - case FQSPI_FLASH_CMD_4QPP: - pctrl->wr_cfg.wr_addr_sel = FQSPI_ADDR_SEL_4; - break; - default: - ret |= FQSPI_NOT_SUPPORT; - return ret; - break; + case FQSPI_FLASH_CMD_PP: + case FQSPI_FLASH_CMD_QPP: + pctrl->wr_cfg.wr_addr_sel = FQSPI_ADDR_SEL_3; + break; + case FQSPI_FLASH_CMD_4PP: + case FQSPI_FLASH_CMD_4QPP: + pctrl->wr_cfg.wr_addr_sel = FQSPI_ADDR_SEL_4; + break; + default: + ret |= FQSPI_NOT_SUPPORT; + return ret; + break; } /*write wr_cfg to Write config register 0x08 */ @@ -802,41 +844,41 @@ FError FQspiFlashErase(FQspiCtrl *pctrl, u8 command, u32 offset) switch (command) { - case FQSPI_FLASH_CMD_SE: - /* set addr_sel region, FQSPI_ADDR_SEL_3 or FQSPI_ADDR_SEL_4 */ - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; + case FQSPI_FLASH_CMD_SE: + /* set addr_sel region, FQSPI_ADDR_SEL_3 or FQSPI_ADDR_SEL_4 */ + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; - /* set cmd_addr region, by command, have addr transfer */ - pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; + /* set cmd_addr region, by command, have addr transfer */ + pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; - /* need some execution time */ - pctrl->cmd_def.wait = FQSPI_WAIT_ENABLE; + /* need some execution time */ + pctrl->cmd_def.wait = FQSPI_WAIT_ENABLE; - break; - case FQSPI_FLASH_CMD_4SE: - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_4; - pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; - pctrl->cmd_def.wait = FQSPI_WAIT_ENABLE; + break; + case FQSPI_FLASH_CMD_4SE: + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_4; + pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; + pctrl->cmd_def.wait = FQSPI_WAIT_ENABLE; - break; - case FQSPI_FLASH_CMD_P4E: - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; - pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; + break; + case FQSPI_FLASH_CMD_P4E: + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; + pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; - break; - case FQSPI_FLASH_CMD_4P4E: - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_4; - pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; + break; + case FQSPI_FLASH_CMD_4P4E: + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_4; + pctrl->cmd_def.cmd_addr = FQSPI_CMD_ADDR_ENABLE; - break; - case FQSPI_FLASH_CMD_BE: - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; - break; - case FQSPI_FLASH_CMD_4BE: - pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; - break; - default: - return FQSPI_NOT_SUPPORT; + break; + case FQSPI_FLASH_CMD_BE: + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; + break; + case FQSPI_FLASH_CMD_4BE: + pctrl->cmd_def.addr_sel = FQSPI_ADDR_SEL_3; + break; + default: + return FQSPI_NOT_SUPPORT; } /*write cmd_reg to Command port register 0x10 */ @@ -968,7 +1010,7 @@ FError FQspiFlashWriteReg(FQspiCtrl *pctrl, u8 command, const u8 *buf, size_t le if (len > 4) { - FQSPI_ERROR("data length exceed. commad 0x%lx, len:%d \n", command, len); + FQSPI_ERROR("Data length exceed. commad 0x%lx, len:%d \n", command, len); return FQSPI_INVAL_PARAM; } else if ((len > 0) && (buf != NULL)) @@ -1014,7 +1056,7 @@ FError FQspiFlashWaitForCmd(FQspiCtrl *pctrl) ret = FQspiFlashSpecialInstruction(pctrl, FQSPI_FLASH_CMD_RDSR1, &sr1, sizeof(sr1)); if (FQSPI_SUCCESS != ret) { - FQSPI_ERROR("failed to read sr1, result 0x%x\r\n", ret); + FQSPI_ERROR("Failed to read sr1, result 0x%x\r\n", ret); return ret; } @@ -1027,7 +1069,7 @@ FError FQspiFlashWaitForCmd(FQspiCtrl *pctrl) if (!timeout) { - FQSPI_ERROR("wait cmd timeout !!!"); + FQSPI_ERROR("Wait cmd timeout !!!"); ret = FQSPI_TIMEOUT; break; } @@ -1035,5 +1077,30 @@ FError FQspiFlashWaitForCmd(FQspiCtrl *pctrl) } while (sr1 & FQSPI_NOR_FLASH_STATE_BUSY); + return ret; +} + +/** + * @name: FQspiFlashWProtectSet + * @msg: Set qspi write protection function + * @param {FQspiCtrl} *pctrl, instance of FQSPI controller + * @param {u32} Write protect function enable/disable 1:enable,0:disable + * @return err code information, FQSPI_SUCCESS indicates success,others indicates failed + */ +FError FQspiFlashWProtectSet(FQspiCtrl *pctrl, boolean wprotect, u8 channel) +{ + FASSERT(pctrl); + FError ret = FQSPI_SUCCESS; + u8 wp_block[2] = {FQSPI_FLASH_WP_ENABLE, FQSPI_FLASH_WP_DISABLE}; + FQspiChannelSet(pctrl, channel); + ret = FQspiFlashEnableWrite(pctrl); + if (wprotect == TRUE) + { + ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, &wp_block[0], 1); + } + else if (wprotect == FALSE) + { + ret = FQspiFlashWriteReg(pctrl, FQSPI_FLASH_CMD_WRR, &wp_block[1], 1); + } return ret; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.h b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.h index 26712ca9b3..0c74afa5c0 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.h +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_flash.h @@ -21,23 +21,27 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct - * 1.2 wangxiaodong 2022.3.27 re-construct - * 1.3 wangxiaodong 2022.7.5 adapt to e2000 + * 1.0 wangxiaodong 2021/11/12 first release + * 1.1 wangxiaodong 2022/3/29 improve functions + * 1.2 wangxiaodong 2022/7/5 adapt to e2000 + * 1.3 wangxiaodong 2022/9/9 improve functions + * 1.4 zhangyan 2022/12/7 improve functions */ -#ifndef BSP_DRIVERS_FQSPI_FLASH_H -#define BSP_DRIVERS_FQSPI_FLASH_H +#ifndef FQSPI_FLASH_H +#define FQSPI_FLASH_H + +#include "fkernel.h" +#include "ftypes.h" +#include "ferror_code.h" +#include "fqspi.h" + #ifdef __cplusplus extern "C" { #endif -#include "fkernel.h" -#include "ftypes.h" -#include "ferror_code.h" -#include "fqspi.h" /* qspi flash support manufacturer JEDEC ID */ #define FQSPI_FLASH_MF_ID_CYPRESS 0x01 @@ -45,17 +49,19 @@ extern "C" #define FQSPI_FLASH_MF_ID_BOYA 0x68 /* qspi flash supported information table */ -#define FQSPI_FLASH_INFO_TABLE \ -{ \ - {"S25FS256S", FQSPI_FLASH_MF_ID_CYPRESS, 0x02, 0x19, FQSPI_FLASH_CAP_32MB}, \ - {"GD25Q32C", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x16, FQSPI_FLASH_CAP_4MB}, \ - {"GD25Q32E", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x60, 0x16, FQSPI_FLASH_CAP_4MB}, \ - {"GD25Q64B", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x17, FQSPI_FLASH_CAP_8MB}, \ - {"GD25LQ128E", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x18, FQSPI_FLASH_CAP_16MB}, \ - {"GD25QL256D", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x60, 0x19, FQSPI_FLASH_CAP_32MB}, \ - {"BY25Q64BS", FQSPI_FLASH_MF_ID_BOYA, 0x40, 0x17, FQSPI_FLASH_CAP_8MB}, \ - {"BY25Q32BS", FQSPI_FLASH_MF_ID_BOYA, 0x40, 0x16, FQSPI_FLASH_CAP_4MB} \ -} +#define FQSPI_FLASH_INFO_TABLE \ + { \ + {"S25FS256S", FQSPI_FLASH_MF_ID_CYPRESS, 0x02, 0x19, FQSPI_FLASH_CAP_32MB}, \ + {"GD25Q32C", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x16, FQSPI_FLASH_CAP_4MB}, \ + {"GD25Q32E", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x60, 0x16, FQSPI_FLASH_CAP_4MB}, \ + {"GD25Q64B", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x17, FQSPI_FLASH_CAP_8MB}, \ + {"GD25LQ128E", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x40, 0x18, FQSPI_FLASH_CAP_16MB}, \ + {"GD25LQ128E", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x60, 0x18, FQSPI_FLASH_CAP_16MB}, \ + {"GD25QL256D", FQSPI_FLASH_MF_ID_GIGADEVICE, 0x60, 0x19, FQSPI_FLASH_CAP_32MB}, \ + {"BY25Q64BS", FQSPI_FLASH_MF_ID_BOYA, 0x40, 0x17, FQSPI_FLASH_CAP_8MB}, \ + {"BY25Q128BS", FQSPI_FLASH_MF_ID_BOYA, 0x40, 0x18, FQSPI_FLASH_CAP_16MB}, \ + {"BY25Q32BS", FQSPI_FLASH_MF_ID_BOYA, 0x40, 0x16, FQSPI_FLASH_CAP_4MB} \ + } #define FQSPI_FLASH_CMD_WRR 0x01 /* Write status register */ #define FQSPI_FLASH_CMD_PP 0x02 /* Page program */ @@ -76,7 +82,9 @@ extern "C" #define FQSPI_FLASH_CMD_RDCR 0x35 /* Read config register */ #define FQSPI_FLASH_CMD_BE 0x60 /* Bulk erase */ #define FQSPI_FLASH_CMD_RDAR 0x65 /* Read Any Register */ +#define FQSPI_FLASH_CMD_DOR 0x3B /* Dual read data bytes*/ #define FQSPI_FLASH_CMD_QOR 0x6B /* Quad read data bytes */ +#define FQSPI_FLASH_CMD_QWFR 0xE7 /* Quad word fast read data bytes */ #define FQSPI_FLASH_CMD_4QOR 0x6C /* Quad read data bytes */ #define FQSPI_FLASH_CMD_WRAR 0x71 /* Write Any Register */ #define FQSPI_FLASH_CMD_RDID 0x9F /* Read JEDEC ID */ @@ -90,14 +98,17 @@ extern "C" #define FQSPI_FLASH_CMD_SFDP 0x5A /* Read JEDEC Serial Manu ID */ #define FQSPI_CMD_ENABLE_RESET 0x66 /* Software Reset Enable */ #define FQSPI_CMD_RESET 0x99 /* Software Reset */ +#define FQSPI_FLASH_CMD_RDSR3 0x15 /* Read status register 3 */ /* boya flash */ #define FQSPI_FLASH_CMD_WRITE_SR2 0x31 /* Write status register 2 */ - +#define FQSPI_FLASH_CMD_WRITE_SR3 0x11 /* Write status register 3 */ #define FQSPI_BUSY_TIMEOUT_US 1000000 #define FQSPI_NOR_FLASH_STATE_BUSY BIT(0) +#define FQSPI_FLASH_WP_ENABLE 0x7c /* Write status register 2 */ +#define FQSPI_FLASH_WP_DISABLE 0x00 /* Write status register 2 */ /* Read some flash information */ FError FQspiFlashSpecialInstruction(FQspiCtrl *pctrl, u8 cmd, u8 *buf, size_t len); @@ -140,6 +151,9 @@ FError FQspiFlashPortWriteData(FQspiCtrl *pctrl, u8 cmd, u32 chip_addr, u8 *buf, /* detect flash information */ FError FQspiFlashDetect(FQspiCtrl *pctrl); +/* qspi write protect set */ +FError FQspiFlashWProtectSet(FQspiCtrl *pctrl, boolean wprotect, u8 channel); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_g.c b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_g.c index e152ccd9f0..14f01cbcd0 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_g.c +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_g.c @@ -14,26 +14,24 @@ * FilePath: fqspi_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:00:41 - * Description:   - * This file is for - * + * Description:  This file is for the qspi default configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct - * 1.2 wangxiaodong 2022.3.27 re-construct + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions */ #include "fparameters.h" #include "fqspi.h" #include "sdkconfig.h" -FQspiConfig FQspiConfigTbl[FQSPI_INSTANCE_NUM] = +FQspiConfig FQspiConfigTbl[FQSPI_NUM] = { { - .instance_id = FQSPI_INSTANCE_0, - .base_addr = FQSPI_BASEADDR, + .instance_id = FQSPI0_ID, + .base_addr = FQSPI_BASE_ADDR, .mem_start = FQSPI_MEM_START_ADDR, .capacity = 0, .dev_num = 0, diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.c b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.c index e759c661a5..a7c7ac3442 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.c @@ -14,13 +14,12 @@ * FilePath: fqspi_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:00:41 - * Description:   - * This file is for - * - * + * Description:  This file is for the qspi register related functions + * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/3/29 first release */ #include "ftypes.h" #include "ferror_code.h" diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.h b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.h index d80c0a1398..2d4dd650a7 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_hw.h @@ -14,12 +14,14 @@ * FilePath: fqspi_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:00:23 - * Description:  This files is for + * Description:  This files is for the qspi register related definition * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct + * Ver   Who        Date        Changes + * ----- ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions + * 1.2 zhangyan 2022/12/7 improve functions */ #ifndef BSP_DRIVERS_FQSPI_HW_H @@ -49,22 +51,22 @@ extern "C" /* FQSPI_CAP */ #define FQSPI_CAP_FLASH_NUM(data) ((data) << 3) /* Flash number */ -#define FQSPI_CAP_FLASH_CAP(data) ((data) << 0) /* The flash capacity */ +#define FQSPI_CAP_FLASH_CAP(data) ((data) << 0) /* The flash capacity */ #define FQSPI_CAP_FLASH_NUM_MASK GENMASK(4, 3) #define FQSPI_CAP_FLASH_CAP_MASK GENMASK(2, 0) /* RD_CFG */ -#define FQSPI_RD_CFG_CMD(data) ((data) << 24) /* Read Command */ -#define FQSPI_RD_CFG_THROUGH(data) ((data) << 23) /* The programming flag in the status register */ +#define FQSPI_RD_CFG_CMD(data) ((data) << 24) /* Read Command */ +#define FQSPI_RD_CFG_THROUGH(data) ((data) << 23) /* The programming flag in the status register */ #define FQSPI_RD_CFG_TRANSFER(data) ((data) << 20) /* rd_tranfer region */ #define FQSPI_RD_CFG_ADDR_SEL(data) ((data) << 19) /* rd_addr_sel region*/ -#define FQSPI_RD_CFG_LATENCY(data) ((data) << 18) /* rd_latency region*/ -#define FQSPI_RD_CFG_MODE_BYTE(data) ((data) << 17) /* mode byte region*/ +#define FQSPI_RD_CFG_LATENCY(data) ((data) << 18) /* rd_latency region*/ +#define FQSPI_RD_CFG_MODE_BYTE(data) ((data) << 17) /* mode byte region*/ #define FQSPI_RD_CFG_CMD_SIGN(data) ((data) << 9) /* cmd_sign region*/ -#define FQSPI_RD_CFG_DUMMY(data) ((data-1) << 4) /* dummy region*/ +#define FQSPI_RD_CFG_DUMMY(data) ((data-1) << 4) /* dummy region*/ #define FQSPI_RD_CFG_D_BUFFER(data) ((data) << 3) /* d_buffer region*/ -#define FQSPI_RD_CFG_SCK_SEL(data) ((data) << 0) /* rd_sck_sel region*/ +#define FQSPI_RD_CFG_SCK_SEL(data) ((data) << 0) /* rd_sck_sel region*/ #define FQSPI_RD_CFG_CMD_MASK GENMASK(31, 24) #define FQSPI_RD_CFG_SCK_SEL_MASK GENMASK(2, 0) @@ -132,7 +134,6 @@ extern "C" #define FQSPI_QUAD_READ_MODE_DISABLE 0xF0BF /* disable FLASH XIP MODE */ #define FQSPI_QUAD_READ_MODE_CMD 0xA0 /* FLASH XIP MODE CMD SIGN */ - typedef enum { FQSPI_CMD_READ = 0x01, diff --git a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_sinit.c b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_sinit.c index d6636990a8..b3d908bda0 100644 --- a/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/qspi/fqspi/fqspi_sinit.c @@ -14,27 +14,28 @@ * FilePath: fqspi_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:01:10 - * Description:  This files is for + * Description:  This files is for getting default configuration of specific qspi instance_id * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.1 wangxiaodong 2021.11.12 re-construct + * Ver   Who         Date        Changes + * -----  ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2022/3/29 first release + * 1.1 wangxiaodong 2022/9/9 improve functions */ #include "fparameters.h" #include "fassert.h" #include "fqspi.h" -extern FQspiConfig FQspiConfigTbl[FQSPI_INSTANCE_NUM]; +extern FQspiConfig FQspiConfigTbl[FQSPI_NUM]; const FQspiConfig *FQspiLookupConfig(u32 instance_id) { - FASSERT(instance_id < FQSPI_INSTANCE_NUM); + FASSERT(instance_id < FQSPI_NUM); const FQspiConfig *pconfig = NULL; u32 index; - for (index = 0; index < (u32)FQSPI_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FQSPI_NUM; index++) { if (FQspiConfigTbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/Kconfig b/bsp/phytium/libraries/standalone/drivers/rtc/Kconfig index 9919d9d29f..63cedcbe5c 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/rtc/Kconfig @@ -3,7 +3,7 @@ menu "FRTC Configuration" bool prompt "Use FRTC" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.c b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.c index 8ee7ad3484..2936a06532 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.c +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.c @@ -12,14 +12,14 @@ * * * FilePath: frtc.c - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:02:33 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:02:33 + * Description:  This file is for user API implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Wangxiaodong 2021/11/5 init + * 1.0 Wangxiaodong 2021/8/26 first commit */ #include @@ -60,19 +60,21 @@ static FError FRtcCheckDateTime(const FRtcDateTime *date_time) /* 闰年2月+1天 */ if ((w_month == 2) && (FRTC_IS_LEAP_YEAR(w_year))) + { days_of_month[w_month - 1] += 1; + } /* 判断月份日期是否合法 */ if ((w_month > 12) || (w_month < 1) || (w_day > days_of_month[w_month - 1]) || (w_day < 1)) { - FRTC_ERROR("invalid input date: month: %d, day: %d", w_month, w_day); + FRTC_ERROR("Invalid input date: month: %d, day: %d", w_month, w_day); return FRTC_ERR_DATE_INVALID; } /* 判断时分秒是否合法 */ if ((w_hour > 23) || (w_minute > 59) || (w_second > 59)) { - FRTC_ERROR("invalid input time: hour: %d, minute: %d, second: %d", + FRTC_ERROR("Invalid input time: hour: %d, minute: %d, second: %d", w_hour, w_minute, w_second); return FRTC_ERR_TIME_INVALID; } @@ -188,10 +190,14 @@ void FRtcReadTimeStamp(FRtcCtrl *pctrl, time_t *sec_p, time_t *msec_p) msec = ((tick * 1000) >> FRTC_COUNTER_HB_OFFSET); if (sec_p) + { *sec_p = sec; + } if (msec_p) + { *msec_p = msec; + } return; } diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.h b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.h index 25fdd276d6..870a8bf7b9 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.h +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc.h @@ -12,29 +12,29 @@ * * * FilePath: frtc.h - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:02:51 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:02:51 + * Description:  This file is for user API definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Wangxiaodong 2021/8/26 init + * 1.0 Wangxiaodong 2021/8/26 first commit */ -#ifndef BSP_DRIVERS_FRTC_H -#define BSP_DRIVERS_FRTC_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef DRIVERS_RTC_FRTC_H +#define DRIVERS_RTC_FRTC_H #include #include "ftypes.h" #include "ferror_code.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef struct { uintptr control_base_addr; /* rtc控制寄存器基地址 */ diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_g.c b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_g.c index e3b54ab488..e7457ccce2 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_g.c +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_g.c @@ -12,14 +12,14 @@ * * * FilePath: frtc_g.c - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:01:26 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:01:26 + * Description:  This file is for rtc static configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Wangxiaodong 2021/8/25 init + * 1.0 Wangxiaodong 2021/8/26 first commit */ #include "fparameters.h" diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.c b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.c index b7d0772096..947077908b 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.c @@ -12,13 +12,14 @@ * * * FilePath: frtc_hw.c - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:01:40 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:01:40 + * Description:  This file is for rtc register read/write operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 Wangxiaodong 2021/8/26 first commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.h b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.h index d104692667..4f1a4ebe4b 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_hw.h @@ -12,28 +12,29 @@ * * * FilePath: frtc_hw.h - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:01:54 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:01:54 + * Description:  This file is for rtc register definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 wangxiaodong 2021/11/5 init + * 1.0 wangxiaodong 2021/8/26 first commit */ -#ifndef BSP_DRIVERS_FRTC_HW_H -#define BSP_DRIVERS_FRTC_HW_H +#ifndef DRIVERS_RTC_FRTC_HW_H +#define DRIVERS_RTC_FRTC_HW_H + + +#include "fkernel.h" +#include "ftypes.h" +#include "fio.h" #ifdef __cplusplus extern "C" { #endif -#include "fkernel.h" -#include "ftypes.h" -#include "fio.h" - /* Rtc register definitions */ #define FRTC_CMR 0x04 diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_intr.c b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_intr.c index 9b7803214b..72b63b241a 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_intr.c @@ -12,14 +12,14 @@ * * * FilePath: frtc_intr.c - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:02:07 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:02:07 + * Description:  This file is for rtc interrupt operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Wangxiaodong 2021/8/3 init + * 1.0 Wangxiaodong 2021/8/26 first commit */ #include "fparameters.h" diff --git a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_sinit.c b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_sinit.c index 7ded7bdbcc..693bdde77c 100644 --- a/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/rtc/frtc/frtc_sinit.c @@ -12,13 +12,14 @@ * * * FilePath: frtc_sinit.c - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:02:24 - * Description:  This files is for + * Date: 2021-08-25 14:53:42 + * LastEditTime: 2021-08-26 09:02:24 + * Description:  This file is for rtc static initialization functionality * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 Wangxiaodong 2021/8/26 first commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/sata/Kconfig b/bsp/phytium/libraries/standalone/drivers/sata/Kconfig index 594bd36606..f2c51a66d4 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/sata/Kconfig @@ -3,7 +3,7 @@ menu "FSATA Configuration" bool prompt "Use FSATA" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.c b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.c index c9fa80705b..381eba09c9 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.c +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.c @@ -14,11 +14,14 @@ * FilePath: fsata.c * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:05:09 - * Description:  This files is for sata ctrl function implementation + * Description:  This file is for sata ctrl function implementation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/9/9 improve functions + * 1.2 wangxiaodong 2022/10/21 improve functions */ #include @@ -116,7 +119,9 @@ static FError FSataAhciLinkUp(FSataCtrl *instance_p, u8 port) { reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_SCR_STAT); if ((reg_val & FSATA_PORT_SCR_STAT_DET_MASK) == FSATA_PORT_SCR_STAT_DET_PHYRDY) + { return FSATA_SUCCESS; + } fsleep_microsec(1000); i++; } @@ -152,7 +157,7 @@ static FError FSataAhciInquiry(FSataCtrl *instance_p, u8 port) (u8 *)tmpid, FSATA_ID_WORDS * 2, FALSE, FALSE); if (ret != FSATA_SUCCESS) { - FSATA_ERROR("FSataAhciInquiry: command failure. ret = %#x", ret); + FSATA_ERROR("FSataAhciInquiry: command failure. ret = %#x.", ret); return FSATA_ERR_OPERATION; } @@ -181,18 +186,24 @@ static void FSataIdentityCopy(unsigned char *dest, unsigned char *src, u32 len) while (start < len) { if (src[start] != 0x20)/* character is not sapce */ + { break; + } start++; } end = len - 1; while (end > start) { if (src[end] != 0x20)/* character is not sapce */ + { break; + } end--; } for (; start <= end; start++) + { *dest ++ = src[start]; + } *dest = '\0'; } @@ -207,9 +218,13 @@ static u64 FSataIdToSectors(u16 *id) if (FSataIdHasLba(id)) { if (FSataIdHasLba48(id)) + { return FSATA_ID_U64(id, FSATA_ID_LBA48_SECTORS); + } else + { return (u64)(FSATA_ID_U32(id, FSATA_ID_LBA_SECTORS)); + } } else { @@ -229,7 +244,9 @@ static void FSataIdStrCopy(u16 *dest, u16 *src, int len) { int i; for (i = 0; i < len / 2; i++) + { dest[i] = __swab16(src[i]); + } } /** @@ -262,7 +279,7 @@ void FSataInfoPrint(FSataInfo *dev_desc) if (dev_desc->type == FSATA_DEV_TYPE_UNKNOWN) { - FSATA_INFO("not available"); + FSATA_INFO("Not available."); return; } @@ -310,7 +327,7 @@ void FSataInfoPrint(FSataInfo *dev_desc) } else { - FSATA_INFO("Capacity: not available"); + FSATA_INFO("Capacity: not available."); } } @@ -342,7 +359,9 @@ static FError FSataAhciReadCapacity(FSataCtrl *instance_p, u8 port, u64 cap64 = FSataIdToSectors(instance_p->ataid[port]); if (cap64 > 0x100000000ULL) + { cap64 = 0xffffffff; + } *capacity = (unsigned long)(cap64); if (*capacity != 0xffffffff) @@ -353,7 +372,7 @@ static FError FSataAhciReadCapacity(FSataCtrl *instance_p, u8 port, } else { - FSATA_DEBUG("should read capacity 16?"); + FSATA_DEBUG("Should read capacity 16?"); } return FSATA_SUCCESS; @@ -457,7 +476,7 @@ static FError FSataAhciReset(FSataCtrl *instance_p) if (i == 0) { - FSATA_ERROR("controller reset failed (0x%x)", reg_val); + FSATA_ERROR("Controller reset failed (0x%x).", reg_val); return FSATA_ERR_TIMEOUT; } @@ -484,7 +503,9 @@ FError FSataAhciInit(FSataCtrl *instance_p) /* reset host control */ ret = FSataAhciReset(instance_p); if (ret != FSATA_SUCCESS) + { return ret; + } /* ahci enable */ FSATA_WRITE_REG32(base_addr, FSATA_HOST_CTL, FSATA_HOST_AHCI_EN); @@ -502,7 +523,9 @@ FError FSataAhciInit(FSataCtrl *instance_p) for (i = 0; i < instance_p->n_ports; i++) { if (!(instance_p->port_map & BIT(i))) + { continue; + } /* set ports base address */ instance_p->port[i].port_base_addr = FSataAhciPortBase(base_addr, i); port_base_addr = instance_p->port[i].port_base_addr; @@ -531,7 +554,7 @@ FError FSataAhciInit(FSataCtrl *instance_p) ret = FSataAhciLinkUp(instance_p, i); if (ret) { - FSATA_DEBUG("sata host %d, port %d link timeout", instance_p->config.instance_id, i); + FSATA_DEBUG("sata host %d, port %d link timeout.", instance_p->config.instance_id, i); continue; } else @@ -542,7 +565,9 @@ FError FSataAhciInit(FSataCtrl *instance_p) /* Clear error status */ reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_SCR_ERR); if (reg_val) + { FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_SCR_ERR, reg_val); + } /* Device presence detected but Phy communication not established, retry once more */ reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_SCR_STAT) & FSATA_PORT_SCR_STAT_DET_MASK; @@ -556,12 +581,16 @@ FError FSataAhciInit(FSataCtrl *instance_p) /* Clear error status */ reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_SCR_ERR); if (reg_val) + { FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_SCR_ERR, reg_val); + } /* clear port irq status */ reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_IRQ_STAT); if (reg_val) + { FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_IRQ_STAT, reg_val); + } /* clear host corresponding port interrupt status register */ FSATA_WRITE_REG32(base_addr, FSATA_HOST_IRQ_STAT, BIT(i)); @@ -569,7 +598,9 @@ FError FSataAhciInit(FSataCtrl *instance_p) /* register linkup ports */ reg_val = FSATA_READ_REG32(port_base_addr, FSATA_PORT_SCR_STAT); if ((reg_val & FSATA_PORT_SCR_STAT_DET_MASK) == FSATA_PORT_SCR_STAT_DET_PHYRDY) + { instance_p->link_port_map |= BIT(i); + } } /* host interrupt enable */ @@ -642,7 +673,7 @@ FError FSataAhciPortStart(FSataCtrl *instance_p, u8 port, uintptr mem) */ if (FSataWaitCmdCompleted(port_base_addr + FSATA_PORT_TFDATA, WAIT_MS_TFD, FSATA_BUSY)) { - FSATA_DEBUG("timeout exit!"); + FSATA_DEBUG("Timeout exit!"); return FSATA_ERR_TIMEOUT; } @@ -738,7 +769,7 @@ static FError FSataAhciDataIO(FSataCtrl *instance_p, u8 port, u8 *fis, if (port >= instance_p->n_ports) { - FSATA_DEBUG("Invalid port number %d", port); + FSATA_DEBUG("Invalid port number %d.", port); return FSATA_ERR_INVAILD_PARAMETER; } @@ -756,7 +787,7 @@ static FError FSataAhciDataIO(FSataCtrl *instance_p, u8 port, u8 *fis, int prdt_length = FSataAhciFillCmdTablePrdt(instance_p, port, buf, buf_len); if (prdt_length == -1) { - FSATA_ERROR("FSataAhciFillCmdTablePrdt failed, buf_len = %d\n", buf_len); + FSATA_ERROR("FSataAhciFillCmdTablePrdt failed, buf_len = %d.\n", buf_len); return FSATA_ERR_INVAILD_PARAMETER; } @@ -771,14 +802,16 @@ static FError FSataAhciDataIO(FSataCtrl *instance_p, u8 port, u8 *fis, /* set tag bit in SACT register before write CI register when use native cmd */ if (is_ncq == TRUE) + { FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_SCR_ACT, FSATA_PORT_SCR_ACT_ENABLE); + } /* send cmd */ FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_CMD_ISSUE, FSATA_PORT_CMD_ISSUE_ENABLE); if (FSataWaitCmdCompleted(port_base_addr + FSATA_PORT_CMD_ISSUE, WAIT_MS_DATAIO, FSATA_PORT_CMD_ISSUE_ENABLE)) { - FSATA_ERROR("timeout exit!"); + FSATA_ERROR("Timeout exit!"); return FSATA_ERR_TIMEOUT; } @@ -816,9 +849,13 @@ FError FSataReadWrite(FSataCtrl *instance_p, u8 port, u32 start, fis[0] = FSATA_FIS_REG_HOST_TO_DEVICE;/* fis type */ fis[1] = FSATA_FIS_REG_HOST_TO_DEVICE_C; /* C and PM Port */ if (is_ncq == FALSE) - fis[2] = is_write ? FSATA_CMD_WRITE_EXT : FSATA_CMD_READ_EXT; /* Command */ + { + fis[2] = is_write ? FSATA_CMD_WRITE_EXT : FSATA_CMD_READ_EXT; /* Command */ + } else - fis[2] = is_write ? FSATA_CMD_FPDMA_WRITE : FSATA_CMD_FPDMA_READ; /* Command */ + { + fis[2] = is_write ? FSATA_CMD_FPDMA_WRITE : FSATA_CMD_FPDMA_READ; /* Command */ + } while (blk_cnt) { @@ -867,7 +904,7 @@ FError FSataReadWrite(FSataCtrl *instance_p, u8 port, u32 start, buffer, transfer_size, is_ncq, is_write); if (ret) { - FSATA_ERROR("scsi_ahci: SCSI command failure. ret = %#x", ret); + FSATA_ERROR("scsi_ahci: SCSI command failure. ret = %#x.", ret); return FSATA_ERR_OPERATION; } diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.h b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.h index d901b34485..74f67ac011 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.h +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata.h @@ -14,24 +14,27 @@ * FilePath: fsata.h * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:05:24 - * Description:  This files is for sata ctrl function definition + * Description:  This file is for sata ctrl function definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/9/9 improve functions + * 1.2 wangxiaodong 2022/10/21 improve functions */ -#ifndef BSP_DRIVERS_FSATA_H -#define BSP_DRIVERS_FSATA_H +#ifndef FSATA_H +#define FSATA_H + +#include "ftypes.h" +#include "ferror_code.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "ftypes.h" -#include "ferror_code.h" -#include "fkernel.h" #define FSATA_SUCCESS FT_SUCCESS #define FSATA_ERR_INVAILD_PARAMETER FT_MAKE_ERRCODE(ErrModBsp, ErrBspSata, 1) @@ -54,7 +57,7 @@ extern "C" #define FSATA_AHCI_CMD_TABLE_SIZE (FSATA_AHCI_CMD_TABLE_HEADER_SIZE + (FSATA_AHCI_PRTD_ITEM_NUM * FSATA_AHCI_PRTD_ITEM_SIZE)) #define FSATA_AHCI_PORT_PRIV_DMA_SZ (FSATA_AHCI_CMD_LIST_HEADER_SIZE * FSATA_AHCI_CMD_LIST_HEADER_NUM + \ - FSATA_AHCI_CMD_TABLE_SIZE + FSATA_AHCI_RX_FIS_SZ) + FSATA_AHCI_CMD_TABLE_SIZE + FSATA_AHCI_RX_FIS_SZ) #define FSATA_AHCI_CMD_ATAPI BIT(5) #define FSATA_AHCI_CMD_WRITE BIT(6) @@ -133,9 +136,13 @@ enum static inline int FSataIdHasLba48(const u16 *id) { if ((id[83] & 0xC000) != 0x4000) + { return 0; + } if (!FSATA_ID_U64(id, 100)) + { return 0; + } return id[83] & BIT(10); } diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_g.c b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_g.c index dc90afa636..f02f0b1060 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_g.c +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_g.c @@ -14,11 +14,13 @@ * FilePath: fsata_g.c * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:03:08 - * Description:  This files is for static config of sata ctrl + * Description:  This file is for static config of sata ctrl * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/10/21 improve functions */ #include "fparameters.h" @@ -79,22 +81,22 @@ const FSataConfig FSataPcieConfigTbl[PLAT_AHCI_HOST_MAX_COUNT] = #if defined(CONFIG_TARGET_E2000) /* configs of controller ahci ctrl */ -const FSataConfig FSataControllerConfigTbl[FSATA_INSTANCE_NUM] = +const FSataConfig FSataControllerConfigTbl[FSATA_NUM] = { [0] = { - .instance_id = FSATA_INSTANCE_0, - .base_addr = FSATA0_BASEADDR, + .instance_id = FSATA0_ID, + .base_addr = FSATA0_BASE_ADDR, .instance_name = "sata0", - .irq_num = FSATA0_IRQNUM /* Irq number */ + .irq_num = FSATA0_IRQ_NUM /* Irq number */ }, [1] = { - .instance_id = FSATA_INSTANCE_1, - .base_addr = FSATA1_BASEADDR, + .instance_id = FSATA1_ID, + .base_addr = FSATA1_BASE_ADDR, .instance_name = "sata1", - .irq_num = FSATA1_IRQNUM /* Irq number */ + .irq_num = FSATA1_IRQ_NUM /* Irq number */ }, diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.c b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.c index 278636bc93..54060db1b8 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.c @@ -14,11 +14,12 @@ * FilePath: fsata_hw.c * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:03:23 - * Description:  This files is for sata register function + * Description:  This file is for sata register function * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.h b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.h index 39c1b8001f..cfe7602779 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_hw.h @@ -14,26 +14,27 @@ * FilePath: fsata_hw.h * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:03:41 - * Description:  This files is for ctrl of sata functions + * Description:  This file is for ctrl of sata functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/10/21 improve functions */ -#ifndef BSP_DRIVERS_FSATA_HW_H -#define BSP_DRIVERS_FSATA_HW_H +#ifndef FSATA_HW_H +#define FSATA_HW_H + +#include "fkernel.h" +#include "ftypes.h" +#include "fio.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "fkernel.h" -#include "ftypes.h" -#include "fio.h" - /************************** Constant Definitions *****************************/ /* SATA register definitions */ @@ -121,7 +122,7 @@ extern "C" #define FSATA_PORT_IRQ_D2H_REG_FIS BIT(0) /* D2H Register FIS rx'd */ #define FSATA_PORT_IRQ_FREEZE FSATA_PORT_IRQ_CONNECT | FSATA_PORT_IRQ_SDB_FIS | \ - FSATA_PORT_IRQ_D2H_REG_FIS | FSATA_PORT_IRQ_PIOS_FIS + FSATA_PORT_IRQ_D2H_REG_FIS | FSATA_PORT_IRQ_PIOS_FIS #define FSATA_PORT_SCR_ACT_ENABLE BIT(0) /* Port Serial ATA Active */ #define FSATA_PORT_CMD_ISSUE_ENABLE BIT(0) /* Port Command Issue enable */ diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_intr.c b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_intr.c index 56fc9dc401..066f54bcbd 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_intr.c @@ -14,18 +14,19 @@ * FilePath: fsata_intr.c * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:03:57 - * Description:  This files is for intrrupt function of Sata ctrl + * Description:  This file is for intrrupt function of Sata ctrl * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/10/21 improve functions */ #include "fassert.h" #include "fdebug.h" #include "fsata.h" #include "fsata_hw.h" -#include "finterrupt.h" /************************** Constant Definitions *****************************/ @@ -60,7 +61,9 @@ void FSataIrqEnable(FSataCtrl *instance_p, u32 int_mask) for (i = 0; i < instance_p->n_ports; i++) { if (!(port & BIT(i))) + { continue; + } uintptr port_base_addr = instance_p->port[i].port_base_addr; FSATA_SETBIT(port_base_addr, FSATA_PORT_IRQ_MASK, int_mask); @@ -84,7 +87,9 @@ void FSataIrqDisable(FSataCtrl *instance_p, u32 int_mask) for (i = 0; i < instance_p->n_ports; i++) { if (!(port & BIT(i))) + { continue; + } uintptr port_base_addr = instance_p->port[i].port_base_addr; @@ -110,29 +115,29 @@ FError FSataSetHandler(FSataCtrl *instance_p, u32 irq_type, void *func_pointer, switch (irq_type) { - case FSATA_PORT_IRQ_D2H_REG_FIS: - instance_p->fsata_dhrs_cb = ((FSataIrqCallBack)(void *)func_pointer); - instance_p->dhrs_args = call_back_ref; - break; + case FSATA_PORT_IRQ_D2H_REG_FIS: + instance_p->fsata_dhrs_cb = ((FSataIrqCallBack)(void *)func_pointer); + instance_p->dhrs_args = call_back_ref; + break; - case FSATA_PORT_IRQ_SDB_FIS: - instance_p->fsata_sdbs_cb = ((FSataIrqCallBack)(void *)func_pointer); - instance_p->sdbs_args = call_back_ref; - break; + case FSATA_PORT_IRQ_SDB_FIS: + instance_p->fsata_sdbs_cb = ((FSataIrqCallBack)(void *)func_pointer); + instance_p->sdbs_args = call_back_ref; + break; - case FSATA_PORT_IRQ_CONNECT: - instance_p->fsata_pcs_cb = ((FSataIrqCallBack)(void *)func_pointer); - instance_p->pcs_args = call_back_ref; - break; + case FSATA_PORT_IRQ_CONNECT: + instance_p->fsata_pcs_cb = ((FSataIrqCallBack)(void *)func_pointer); + instance_p->pcs_args = call_back_ref; + break; - case FSATA_PORT_IRQ_PIOS_FIS: - instance_p->fsata_pss_cb = ((FSataIrqCallBack)(void *)func_pointer); - instance_p->pss_args = call_back_ref; - break; + case FSATA_PORT_IRQ_PIOS_FIS: + instance_p->fsata_pss_cb = ((FSataIrqCallBack)(void *)func_pointer); + instance_p->pss_args = call_back_ref; + break; - default: - status = (FSATA_ERR_OPERATION); - break; + default: + status = (FSATA_ERR_OPERATION); + break; } return status; } @@ -162,7 +167,9 @@ void FSataIrqHandler(s32 vector, void *param) for (i = 0; i < instance_p->n_ports; i++) { if (!(port & BIT(i))) + { continue; + } port_base_addr = instance_p->port[i].port_base_addr; irq_state = FSATA_READ_REG32(base_addr, FSATA_HOST_IRQ_STAT); diff --git a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_sinit.c b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_sinit.c index 8f0af5c686..b9cfa41b26 100644 --- a/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/sata/fsata/fsata_sinit.c @@ -14,11 +14,13 @@ * FilePath: fsata_sinit.c * Date: 2022-02-10 14:55:11 * LastEditTime: 2022-02-18 09:04:15 - * Description:  This files is for sata static init + * Description:  This file is for sata static init * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/2/10 first release + * 1.1 wangxiaodong 2022/10/21 improve functions */ /***************************** Include Files *********************************/ @@ -41,7 +43,7 @@ extern const FSataConfig FSataPcieConfigTbl[PLAT_AHCI_HOST_MAX_COUNT]; #if defined(CONFIG_TARGET_E2000) - extern const FSataConfig FSataControllerConfigTbl[FSATA_INSTANCE_NUM]; + extern const FSataConfig FSataControllerConfigTbl[FSATA_NUM]; #endif /*****************************************************************************/ @@ -57,7 +59,7 @@ const FSataConfig *FSataLookupConfig(u32 instance_id, u8 type) if (type == FSATA_TYPE_CONTROLLER) { #if defined(CONFIG_TARGET_E2000) - FASSERT(instance_id < FSATA_INSTANCE_NUM); + FASSERT(instance_id < FSATA_NUM); pconfig = &FSataControllerConfigTbl[instance_id]; #endif } diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/Kconfig b/bsp/phytium/libraries/standalone/drivers/scmi/Kconfig new file mode 100644 index 0000000000..040726be74 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/Kconfig @@ -0,0 +1,7 @@ +menu "Scmi Configuration" + config ENABLE_SCMI_MHU + bool + prompt "Use Scmi MHU" + default n + +endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.c new file mode 100644 index 0000000000..6636ffb480 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.c @@ -0,0 +1,75 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fmhu.c + * Date: 2022-12-29 18:07:32 + * LastEditTime: 2022-12-29 18:07:32 + * Description:  This file is for mhu channel binding + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/04 init + */ + +#include "fassert.h" +#include "fmhu.h" +#include "fmhu_hw.h" +/** + * @name: + * @msg: + * @return {*} + * @param {FScmiMhu} *instance_p + * @param {int} chan + */ +void FMhuChanProbe(FScmiMhu *instance_p) +{ + FASSERT(instance_p); + + instance_p->tx_complete = FALSE; + instance_p->msg_count = 0U; + + instance_p->send_data = FMhuSendData; + instance_p->startup = FMhuStartup; + instance_p->shutdown = FMhuShutdown; + instance_p->last_tx_done = FMhuLastTxDone; + + instance_p->mhu.is_ready = FT_COMPONENT_IS_READY; + + instance_p->startup(instance_p->mhu.config.base_addr); + return; +} + +/** + * @name: + * @msg: + * @return {*} + * @param {FScmiMhu} *instance_p + * @param {int} chan + */ +void FMhuChanRemove(FScmiMhu *instance_p) +{ + FASSERT(instance_p); + + instance_p->tx_complete = TRUE; + + instance_p->send_data = NULL; + instance_p->startup = NULL; + instance_p->shutdown = NULL; + instance_p->last_tx_done = NULL; + + instance_p->mhu.is_ready = 0U; + + instance_p->shutdown(instance_p->mhu.config.base_addr); + return; +} diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.h new file mode 100644 index 0000000000..304eb0d771 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu.h @@ -0,0 +1,87 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fmhu.h + * Date: 2022-12-29 18:07:43 + * LastEditTime: 2022-12-29 18:07:43 + * Description:  This file is for mhu function support and data struct + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/04 init + */ +#ifndef FMHU_H +#define FMHU_H + +#include "ftypes.h" +#include "ferror_code.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************** Constant Definitions *****************************/ +#define FMHU_SUCCESS FT_SUCCESS +#define FMHU_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspMhu, 1) +#define FMHU_ERR_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspMhu, 2) +#define FMHU_ERR_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMhu, 3) +#define FMHU_ERR_NOT_SUPPORT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMhu, 4) +#define FMHU_ERR_INVAL_STATE FT_MAKE_ERRCODE(ErrModBsp, ErrBspMhu, 5) + +#define FSCMI_MBOX_TX_QUEUE_LEN 20 + +typedef void (*FMhuEvtHandler)(void *instance_p, void *param); + +typedef struct +{ + u32 mhu_chan_id; /* Mhu chan id */ + uintptr base_addr; /* Device base address */ + u32 irq_num; /* Device intrrupt id */ + u32 irq_prority; /* Device intrrupt priority */ + u32 work_mode; /* Device work mode intr or poll */ +} FMhuConfig; + +typedef struct +{ + FMhuConfig config; /* Current active configs */ + u32 is_ready; /* Device is initialized and ready */ + volatile u32 status; /* Mhu working or idle */ + FMhuEvtHandler slot_msg_recv;/* for interrupt handle */ +} FMhu; + +typedef struct +{ + FMhu mhu;/* mbox object instance */ + boolean tx_complete ; + /* send message */ + u32 msg_count, msg_free; + void *msg_data[FSCMI_MBOX_TX_QUEUE_LEN]; + void *payload; /* share memory */ + void (*send_data)( uintptr addr , u32 chan); + void (*startup)( uintptr addr ); + void (*shutdown)( uintptr addr ); + u32 (*last_tx_done)( uintptr addr ); +} FScmiMhu; + +void FMhuGetDefConfig(FMhuConfig *config_p,u32 chan_id); +void FMhuChanProbe(FScmiMhu *instance_p); +void FMhuChanRemove(FScmiMhu *instance_p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_g.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_g.c new file mode 100644 index 0000000000..355418e364 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_g.c @@ -0,0 +1,40 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fmhu_g.c + * Date: 2022-12-29 16:41:46 + * LastEditTime: 2022-12-29 16:41:46 + * Description:  This file is for get default configs + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/12/30 init + */ + +#include +#include "ftypes.h" +#include "fparameters.h" +#include "fmhu.h" +#include "fassert.h" + +void FMhuGetDefConfig(FMhuConfig *config_p,u32 chan_id) +{ + FASSERT(NULL != config_p); + + memset(config_p, 0, sizeof(config_p)); + config_p->base_addr = FSCMI_MHU_BASE_ADDR; + config_p->irq_num = FSCMI_MHU_IRQ_NUM; + config_p->mhu_chan_id = chan_id; + config_p->work_mode = TRUE; +} diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_hw.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_hw.h new file mode 100644 index 0000000000..0e7c8c2d76 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_hw.h @@ -0,0 +1,144 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fmhu_hw.h + * Date: 2022-12-29 16:40:54 + * LastEditTime: 2022-12-29 16:40:55 + * Description:  This file is for mhu hardware define + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/12/30 init + */ +#ifndef FMHU_HW_H +#define FMHU_HW_H + +#include "fio.h" +#include "fkernel.h" +#include "ftypes.h" +#include "ferror_code.h" +#include "fassert.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define AP_OS_STAT_OFFSET 0x100 +#define AP_OS_SET_OFFSET 0x108 +#define AP_OS_CLR_OFFSET 0x110 + +#define AP_OS_INT_OFFSET 0x508 + +#define FMHU_DATA_MASK GENMASK(31, 0) + +#define FMHU_READ_REG32(addr, reg_offset) FtIn32((addr) + (u32)(reg_offset)) +#define FMHU_WRITE_REG32(addr, reg_offset, reg_value) FtOut32((addr) + (u32)(reg_offset), (u32)(reg_value)) + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define FMHU_READ_STAT(addr) (u32)(FMHU_DATA_MASK & FMHU_READ_REG32(addr, AP_OS_STAT_OFFSET)) + +#define FMHU_READ_SECU(addr) (u32)((u32)(1U << 31) & FMHU_READ_REG32(addr, AP_OS_STAT_OFFSET)) + +#define FMHU_WRITE_SET(addr, dat) FMHU_WRITE_REG32((addr), AP_OS_SET_OFFSET, (dat)) + +#define FMHU_WRITE_CLR(addr, dat) FMHU_WRITE_REG32((addr), AP_OS_CLR_OFFSET, (dat)) + +#define FMHU_WRITE_INT(addr, dat) FMHU_WRITE_REG32((addr), AP_OS_INT_OFFSET, (dat)) + +/************************** Function Prototypes ******************************/ + +/** + * @name: FMhuGetChanStatus + * @msg: Mhu get channel status + * @return {*} + * @param {uintptr} addr + */ +static inline u32 FMhuGetChanStatus(uintptr addr) +{ + FASSERT(addr); + + return FMHU_READ_STAT(addr); +} + +/** + * @name: FMhuSendData + * @msg: Mhu write the AP_OS_SET register to send share memory Data + * @return {*} + * @param {uintptr} addr + * @param {u32} chan + */ +static inline void FMhuSendData(uintptr addr, u32 chan) +{ + FASSERT(addr); + + FMHU_WRITE_SET(addr, chan); + + return; +} + +/** + * @name: FMhuStartup + * @msg: + * @return {*} + * @param {uintptr} addr + */ +static inline void FMhuStartup(uintptr addr) +{ + FASSERT(addr); + + u32 val; + + val = FMHU_READ_STAT(addr); + FMHU_WRITE_CLR(addr, val); + + /* irq set */ + + return; +} + +/** + * @name: FMhuShutdown + * @msg: + * @return {*} + * @param {uintptr} addr + */ +static inline void FMhuShutdown(uintptr addr) +{ + FASSERT(addr); + + FMHU_WRITE_INT(addr,1); + + return; +} + +/** + * @name: FMhuLastTxDone + * @msg: + * @return {*} + * @param {uintptr} addr + */ +static inline u32 FMhuLastTxDone(uintptr addr) +{ + FASSERT(addr); + + return (FMHU_READ_SECU(addr) == (u32)(1U << 31)); +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/board/common/fsmp.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_intr.c similarity index 54% rename from bsp/phytium/libraries/standalone/board/common/fsmp.h rename to bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_intr.c index b0ee12f339..8c661fd6dd 100644 --- a/bsp/phytium/libraries/standalone/board/common/fsmp.h +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fmhu_intr.c @@ -1,34 +1,23 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: fsmp.h - * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-17 17:58:18 - * Description:  This files is for - * - * Modify History: + * See the Phytium Public License for more details. + * + * + * FilePath: fmhu_intr.c + * Date: 2022-12-29 16:42:08 + * LastEditTime: 2022-12-29 16:42:08 + * Description:  This file is for intr mode + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 0.0.1 liushengming 2022/12/29 create file */ - - -#ifndef BSP_BOARD_COMMON_SMP_H -#define BSP_BOARD_COMMON_SMP_H - -#include "ftypes.h" - -void SpinLockInit(unsigned long global_addr); -void SpinLock(void); -void SpinUnlock(void); - -#endif // DEBUG \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.c new file mode 100644 index 0000000000..e26af9b62d --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.c @@ -0,0 +1,347 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi.c + * Date: 2022-12-30 18:32:28 + * LastEditTime: 2022-12-30 18:32:28 + * Description: This file is for scmi protocol support + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liushengming 2023/01/30 init + */ +#include +#include "fscmi.h" +#include "fmhu_hw.h" +#include "fio.h" +#include "fkernel.h" +#include "fdebug.h" +#include "fsleep.h" +#include "fassert.h" +#include "fscmi_base.h" +#include "fscmi_sensors.h" +#include "fscmi_perf.h" + +#define FSCMI_DEBUG_TAG "FSCMI" +#define FSCMI_ERROR(format, ...) FT_DEBUG_PRINT_E(FSCMI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_WARN(format, ...) FT_DEBUG_PRINT_W(FSCMI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_INFO(format, ...) FT_DEBUG_PRINT_I(FSCMI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSCMI_DEBUG_TAG, format, ##__VA_ARGS__) + +#define MSG_ID_MASK GENMASK(7, 0) +#define MSG_TYPE_MASK GENMASK(9, 8) +#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10) +#define MSG_TOKEN_ID_MASK GENMASK(27, 18) + + +FError FScmiDoTransport(FScmi *instance_p,struct FScmiTransferInfo *info, u32 protocol_index) +{ + FError ret; + u32 tx_done = 0; + u32 chan_status = 0; + u32 delay_out = 0; + FMhuConfig *mhu_config = &instance_p->scmi_mhu.mhu.config; + + /* write data to share buffer */ + ret = FScmiProtocolTxPrepare(instance_p,protocol_index); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("%s,FScmiProtocolTxPrepare is error", __FUNCTION__); + return ret; + } + + if(instance_p->scmi_mhu.send_data) + { + instance_p->scmi_mhu.send_data(mhu_config->base_addr,mhu_config->mhu_chan_id); + } + chan_status = FMhuGetChanStatus(mhu_config->base_addr); + /* 等待发送完成 */ + while (tx_done == 0) + { + tx_done = instance_p->scmi_mhu.last_tx_done(mhu_config->base_addr); + if (tx_done == 1) + { + break; + } + else + { + fsleep_millisec(10); + delay_out++; + if (delay_out == 10) + { + FSCMI_ERROR("Send error,addr:0x%x,last_tx_done:0x%x",mhu_config->base_addr,tx_done); + return FSCMI_ERROR_WAIT_MBOX_TIMEOUT; + } + } + } + + /* 等待数据接收完成 */ + /* poll way */ + + if(info->poll_completion) + { + while(FScmiProtocolPollDone(instance_p,protocol_index) != TRUE); + /* get data */ + ret = FScmiFetchResponse(instance_p,protocol_index); + if(ret != FT_SUCCESS) + { + return FSCMI_ERROR_FETCH_RESPONSE; + } + } + else + { + /* interrupt way */ + } + + return FT_SUCCESS; +} +/** + * @name: + * @msg: + * @return {*} + * @param {u8} pro_id + * @param {u32} *protocol_index + */ +static FError FScmiProtocolMapping(const u8 pro_id,u32 *protocol_index) +{ + switch (pro_id) + { + case SCMI_PROTOCOL_BASE: + { + *protocol_index = BASE_PROTOCOL_INDEX; + return FT_SUCCESS; + } + case SCMI_PROTOCOL_PERF: + { + *protocol_index = PERF_DOMAIN_INDEX; + return FT_SUCCESS; + } + case SCMI_PROTOCOL_SENSOR: + { + *protocol_index = SENSOR_MANAGEMENT_INDEX; + return FT_SUCCESS; + } + default: + return FSCMI_ERROR_NOT_FOUND; + } + return FT_SUCCESS; +} + +struct FScmiTransferInfo *FScmiGetInfo(FScmi *instance_p, u8 pro_id) +{ + u32 index_id = 0; + FError ret; + ret = FScmiProtocolMapping(pro_id, &index_id); + if (ret != FT_SUCCESS) + { + FSCMI_ERROR("%s,Protocol mapping error", __FUNCTION__); + return NULL; + } + + return &instance_p->info[index_id]; +} + +FError FScmiFetchResponse(FScmi *instance_p, u8 pro_id) +{ + struct FScmiSharedMem *mem =(struct FScmiSharedMem *) instance_p->config.share_mem; + struct FScmiTransferInfo *trans_info; + u32 index_id = 0; + FError ret; + ret = FScmiProtocolMapping(pro_id, &index_id); + if (ret != FT_SUCCESS) + { + FSCMI_ERROR("%s,Protocol mapping error", __FUNCTION__); + return ret; + } + trans_info = &instance_p->info[index_id]; + trans_info->hdr.status = FtIn32((uintptr)mem->msg_payload); + /* Skip the length of header and statues in payload area i.e 8 bytes*/ + trans_info->rx.len = min(trans_info->rx.len, FtIn32((uintptr)(&mem->length)) - 8); + + /* Take a copy to the rx buffer.. */ + + if(trans_info->rx.len) + { + for (u32 i = 0; i < trans_info->rx.len; i++) + { + trans_info->rx.buf[i] = mem->msg_payload[i+4]; + } + } + + return FT_SUCCESS; +} + +FError FScmiProtocolPollDone(FScmi *instance_p,u8 pro_id) +{ + struct FScmiSharedMem *mem =(struct FScmiSharedMem *) instance_p->config.share_mem; + u32 index_id = 0; + FError ret; + ret = FScmiProtocolMapping(pro_id, &index_id); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("%s,Protocol mapping error",__FUNCTION__); + return FALSE; + } + + return FtIn32((uintptr)(&mem->channel_status)) & + (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); +} + + +static u32 FScmiPackHeader(struct FScmiMsgHdr *hdr_p) +{ + + return FIELD_PREP(MSG_ID_MASK, hdr_p->id) | + FIELD_PREP(MSG_TOKEN_ID_MASK, hdr_p->seq) | + FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr_p->protocol_id); +} + +FError FScmiProtocolTxPrepare(FScmi *instance_p,u8 pro_id) +{ + struct FScmiSharedMem *mem =(struct FScmiSharedMem *) instance_p->config.share_mem; + struct FScmiTransferInfo *trans_info; + u32 index_id = 0; + u32 time_out; + FError ret; + static int is_init = 0; + ret = FScmiProtocolMapping(pro_id, &index_id); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("Protocol mapping error"); + return ret; + } + trans_info = &instance_p->info[index_id]; + if(!is_init) + { + FtOut32((uintptr)&mem->channel_status,SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); + is_init = 1; + } + + while (0 == (FtIn32((uintptr)&mem->channel_status) &SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) + { + time_out++; + fsleep_millisec(10); + if (time_out == 10) + { + FSCMI_ERROR("Memory of scmi status error,please check mhu channel set or memory addrs..."); + return FSCMI_ERROR_WAIT_MEM_TIMEOUT; + } + } + + FtOut32((uintptr)&mem->channel_status,0); + FtOut32((uintptr)&mem->flags, 0); + FtOut32((uintptr)&mem->length, sizeof(mem->msg_header) + trans_info->tx.len); + FtOut32((uintptr)&mem->msg_header,FScmiPackHeader(&trans_info->hdr)); + + if(trans_info->tx.len) + { + for (u32 i = 0; i < trans_info->tx.len; i++) + { + mem->msg_payload[i] = trans_info->tx.buf[i]; + } + } + + return FT_SUCCESS; +} + +FError FScmiMessageInit(FScmi *instance_p,u8 msg_id,u8 pro_id,u32 tx_size,u32 rx_size,u8 *tx_buffer) +{ + u32 index_id = 0; + FError ret; + struct FScmiTransferInfo *trans_info; + + ret = FScmiProtocolMapping(pro_id, &index_id); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("Protocol mapping error"); + return ret; + } + trans_info = &instance_p->info[index_id]; + + /* 检查 tx_size / rx_size 的长度*/ + if(tx_size > FSCMI_MSG_SIZE || rx_size > FSCMI_MSG_SIZE) + { + return FSCMI_ERROR_RANGE; + } + + if(tx_size > 0 && tx_buffer == NULL) + { + return FSCMI_ERROR_NULL_POINTER; + } + + /* init hdr */ + trans_info->hdr.seq = pro_id + msg_id ; + trans_info->hdr.id = msg_id; + trans_info->hdr.protocol_id = pro_id; + + /* init buffer */ + trans_info->tx.len = tx_size; + if(tx_size && tx_buffer) + { + memcpy(trans_info->tx.buf, tx_buffer, tx_size); + } + + trans_info->rx.len = rx_size ? :FSCMI_MSG_SIZE;/* */ + trans_info->poll_completion = TRUE; + + return FT_SUCCESS; + +} + + +FError FScmiCfgInitialize(FScmi *instance_p, const struct FScmiConfig *config) +{ + /* first init */ + instance_p->config = *config; + + FError ret; + + /* Second choice is the mbox driver */ + if (instance_p->config.mbox_type == FSCMI_MBOX_MHU_TYPE) + { + FMhuChanProbe(&instance_p->scmi_mhu); + } + else + { + return FSCMI_ERROR_TYPE; + } + + instance_p->config.share_mem = config->share_mem; + + /* The third initializes the base protocol */ + ret = FScmiBaseInit(instance_p); + if (instance_p->revision.version != FSCMI_VERSION) + { + return FSCMI_ERROR_VERSION; + } + + ret = FScmiSensorInit(instance_p); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("FScmiSensorInit init error.Error code:0x%x.",ret); + return FSCMI_ERROR_INIT; + } + + ret = FScmiPerfInit(instance_p); + if(ret != FT_SUCCESS) + { + FSCMI_ERROR("FScmiPerfInit init error.Error code:0x%x.",ret); + return FSCMI_ERROR_INIT; + } + /* Finally confirm the completion status */ + instance_p->is_ready = FT_COMPONENT_IS_READY; + + return FT_SUCCESS; +} diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.h new file mode 100644 index 0000000000..8e3e65f1bd --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi.h @@ -0,0 +1,216 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi.h + * scmi.h + * Date: 2022-12-30 18:32:33 + * LastEditTime: 2022-12-30 18:32:33 + * Description: This file is for scmi protocol struct and application interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liushengming 2023/01/31 init + */ + + +#ifndef FSCMI_H +#define FSCMI_H + +#include "ftypes.h" +#include "ferror_code.h" +#include "fmhu.h" +#include "fparameters.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* error code */ + +#define FSCMI_ERROR_TYPE FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x1u) +#define FSCMI_ERROR_RANGE FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x2u) +#define FSCMI_ERROR_NOT_FOUND FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x3u) +#define FSCMI_ERROR_NULL_POINTER FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x4u) +#define FSCMI_ERROR_WAIT_MBOX_TIMEOUT FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x5u) +#define FSCMI_ERROR_WAIT_MEM_TIMEOUT FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x6u) +#define FSCMI_ERROR_FETCH_RESPONSE FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x7u) +#define FSCMI_ERROR_REQUEST FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x8u) +#define FSCMI_ERROR_VERSION FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0x9u) +#define FSCMI_ERROR_INIT FT_CODE_ERR(ErrModBsp, ErrBspScmi, 0xau) + +#define FSCMI_MBOX_MHU_TYPE 0 +#define FSCMI_VERSION 0x20000 +/* + * SCMI specification requires all parameters, message headers, return + * arguments or any protocol data to be expressed in little endian + * format only. + */ +struct FScmiSharedMem { + u32 reserved; + u32 channel_status; +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1) +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0) + u32 reserved1[2]; + u32 flags; +#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0) + u32 length; + u32 msg_header; + u8 msg_payload[0]; +}; + +enum FScmiStdProtocol { + SCMI_PROTOCOL_BASE = 0x10, + SCMI_PROTOCOL_POWER = 0x11, + SCMI_PROTOCOL_SYSTEM = 0x12, + SCMI_PROTOCOL_PERF = 0x13, + SCMI_PROTOCOL_CLOCK = 0x14, + SCMI_PROTOCOL_SENSOR = 0x15, +}; + +enum FScmiProtocolIndex +{ + BASE_PROTOCOL_INDEX , + PERF_DOMAIN_INDEX , + SENSOR_MANAGEMENT_INDEX , + FSCMI_SUPPORT_PROTOCOL_NUM , +}; + +/* base protocol */ +struct FScmiRevisionInfo +{ + u32 version; + u16 major_ver; + u16 minor_ver; + u8 num_protocols; + u8 num_agents; + u32 impl_ver; + char vendor_id[FSCMI_MAX_STR_SIZE]; + char sub_vendor_id[FSCMI_MAX_STR_SIZE]; +}; + +/* Sensor protocol */ +struct FScmiSensorInfo { + u32 id; + u8 type; + char name[FSCMI_MAX_STR_SIZE]; +}; + +struct FScmiSensorsInfo { + u32 version; + u16 major_ver; + u16 minor_ver; + u32 num_sensors; + u32 max_requests; + u64 reg_addr; + u32 reg_size; + struct FScmiSensorInfo sensor_info[FSCMI_MAX_NUM_SENSOR];/* TS0 TS1 */ +}; + +/* Performance domain protocol */ + +struct FScmiOpp { + u32 perf_val; + u32 power; + u32 trans_latency_us; +}; + +struct FPerfDomInfo { + boolean set_limits; + boolean set_perf; + boolean perf_limit_notify; + boolean perf_level_notify; + u32 opp_count; + u32 sustained_freq_khz; + u32 sustained_perf_level; + u32 mult_factor; + char name[FSCMI_MAX_STR_SIZE]; + struct FScmiOpp opp[FSCMI_MAX_OPPS]; +}; + +struct FScmiPerfInfo { + u32 version; + u16 major_ver; + u16 minor_ver; + u32 num_domains; + boolean power_scale_mw; + u64 stats_addr; + u32 stats_size; + struct FPerfDomInfo dom_info[FSCMI_MAX_PERF_DOMAINS]; +}; + +/* Scmi massage package */ +struct FScmiMsgHdr +{ + u8 id; /* message id */ + u8 protocol_id; /* protocol id */ + u16 seq; /* message token */ + u32 status; /* protocal status */ +}; + +struct FScmiMsg +{ + u8 buf[FSCMI_MSG_SIZE]; /* buffer in normal memory */ + u32 len; /* buffer length */ +}; + +struct FScmiTransferInfo +{ + struct FScmiMsgHdr hdr ; /* Message(Tx/Rx) header */ + struct FScmiMsg tx ; + struct FScmiMsg rx ; + boolean poll_completion; +}; + +/* Scmi protocol struct */ +struct FScmiConfig +{ + uintptr share_mem; /* Chan transport protocol shared memory */ + u32 mbox_type; /* select mbox driver */ +}; + +typedef struct +{ + u32 is_ready; /* Device is ininitialized and ready*/ + struct FScmiConfig config; + struct FScmiRevisionInfo revision; + struct FScmiSensorsInfo sensors; + struct FScmiPerfInfo perf; + struct FScmiTransferInfo info[FSCMI_SUPPORT_PROTOCOL_NUM]; + u8 protocols_imp[FSCMI_MAX_PROTOCOLS_IMP];/* List of protocols implemented, currently maximum of FSCMI_MAX_PROTOCOLS_IMP elements allocated by the base protocol */ + FScmiMhu scmi_mhu; +} FScmi; + +/* Base protocol function */ +FError FScmiCfgInitialize(FScmi *instance_p, const struct FScmiConfig *config); +FError FScmiMessageInit(FScmi *instance_p, u8 msg_id, u8 pro_id, u32 tx_size, u32 rx_size, u8 *tx_buffer); +FError FScmiProtocolTxPrepare(FScmi *instance_p, u8 pro_id); +FError FScmiProtocolPollDone(FScmi *instance_p, u8 pro_id); +FError FScmiFetchResponse(FScmi *instance_p, u8 pro_id); +struct FScmiTransferInfo *FScmiGetInfo(FScmi *instance_p, u8 pro_id); +FError FScmiDoTransport(FScmi *instance_p, struct FScmiTransferInfo *info, u32 protocol_index); +/* Sensor protocol function */ +FError FScmiSensorGetTemp(FScmi *instance_p, u32 sensor_id,s64 *temp); +/* Performance domain function */ +FError FScmiDvfsFreqSet(FScmi *instance_p, u32 domain, u64 freq, boolean poll); +FError FScmiDvfsFreqGet(FScmi *instance_p, u32 domain, u64 *freq, boolean poll); +u64 FScmiPerfGetOppFreq(FScmi *instance_p, u32 domain, u32 opp_num); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.c new file mode 100644 index 0000000000..75e7e9168c --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.c @@ -0,0 +1,371 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_base.c + * Date: 2022-12-31 21:38:31 + * LastEditTime: 2022-12-31 21:47:30 + * Description: This file is for base protocol + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/12 init + */ + +#include +#include "fscmi.h" +#include "fscmi_base.h" +#include "fio.h" +#include "fdebug.h" +#include "fsleep.h" +#include "ftypes.h" +#include "fswap.h" +#include "fkernel.h" + +#define FSCMI_BASE_DEBUG_TAG "FSCMI_BASE" +#define FSCMI_BASE_ERROR(format, ...) FT_DEBUG_PRINT_E(FSCMI_BASE_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_BASE_WARN(format, ...) FT_DEBUG_PRINT_W(FSCMI_BASE_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_BASE_INFO(format, ...) FT_DEBUG_PRINT_I(FSCMI_BASE_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_BASE_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSCMI_BASE_DEBUG_TAG, format, ##__VA_ARGS__) + +struct FScmiBaseAttributes { + u8 num_protocols; + u8 num_agents; + u16 reserved; +}; + +static FError FScmiBaseGetVersion(FScmi *instance_p,u32 *rev_info) +{ + FError ret; + struct FScmiTransferInfo *info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, FSCMI_BASE_PROTOCOL_VERSION, SCMI_PROTOCOL_BASE, 0, sizeof(*rev_info),info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + *rev_info = FtIn32((uintptr)info->rx.buf); + + return FT_SUCCESS; +} + +static FError FScmiBaseGetVendor(FScmi *instance_p,boolean sub_vendor) +{ + FError ret; + struct FScmiTransferInfo *info; + u8 cmd; + char *vendor_id; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + if (sub_vendor) { + cmd = FSCMI_BASE_PROTOCOL_DISCOVER_SUB_VENDOR; + vendor_id = instance_p->revision.sub_vendor_id; + } else { + cmd = FSCMI_BASE_PROTOCOL_DISCOVER_VENDOR; + vendor_id = instance_p->revision.vendor_id; + } + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, cmd, SCMI_PROTOCOL_BASE, 0, FSCMI_MAX_STR_SIZE,info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + memcpy(vendor_id,info->rx.buf,FSCMI_MAX_STR_SIZE); + + return FT_SUCCESS; +} + +static FError FScmiBaseGetAttributes(FScmi *instance_p, u8 *num_protocols, u8 *num_agents) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiBaseAttributes *attr_info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, FSCMI_BASE_PROTOCOL_ATTRIBUTES, SCMI_PROTOCOL_BASE, 0, sizeof(*attr_info),info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + attr_info = (struct FScmiBaseAttributes *)info->rx.buf; + instance_p->revision.num_protocols = attr_info->num_protocols; + instance_p->revision.num_agents = attr_info->num_agents; + + return FT_SUCCESS; +} + +static FError FScmiBaseGetImplementVersion(FScmi *instance_p, u32 *impl_ver) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiBaseAttributes *attr_info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, FSCMI_BASE_PROTOCOL_DISCOVER_IMPLEMENTATION_VERSION, SCMI_PROTOCOL_BASE, 0, sizeof(*impl_ver),info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + *impl_ver = FtIn32((uintptr)info->rx.buf); + + return FT_SUCCESS; +} + +static FError FScmiBaseGetImplementList(FScmi *instance_p , u8 *protocols_imp) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiBaseAttributes *attr_info; + + u32 *num_skip, *num_ret; + u8 *list; + u32 tot_num_ret = 0, loop_num_ret; + u32 loop; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, FSCMI_BASE_PROTOCOL_DISCOVER_LIST_PROTOCOLS, SCMI_PROTOCOL_BASE, sizeof(*num_skip), 0,info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + num_skip = (u32 *)info->tx.buf; + num_ret = (u32 *)info->rx.buf; + list = info->rx.buf + sizeof(num_ret); + + do { + /* Set the number of protocols to be skipped/already read */ + *num_skip = tot_num_ret; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + loop_num_ret = (*num_ret); + + if (tot_num_ret + loop_num_ret > FSCMI_MAX_PROTOCOLS_IMP) + { + FSCMI_BASE_ERROR("No. of Protocol > MAX_PROTOCOLS_IMP"); + break; + } + + for (loop = 0; loop < loop_num_ret; loop++) + protocols_imp[tot_num_ret + loop] = *(list + loop); + + tot_num_ret += loop_num_ret; + } while (loop_num_ret); + + return FT_SUCCESS; +} + +static FError FScmiBaseGetAgent(FScmi *instance_p,int id,char *name) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiBaseAttributes *attr_info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_BASE); + if (info == NULL) + { + FSCMI_BASE_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_BASE); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, FSCMI_BASE_PROTOCOL_DISCOVER_AGENT, SCMI_PROTOCOL_BASE, sizeof(u32), FSCMI_MAX_STR_SIZE,info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + *info->tx.buf = id; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_BASE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Transport package error ,protocol id is %d",SCMI_PROTOCOL_BASE); + return ret; + } + + /* Fill in the obtained parameters */ + memcpy(name, info->rx.buf, FSCMI_MAX_STR_SIZE); + + return FT_SUCCESS; +} + +/** + * @name: FScmiBaseInit + * @msg: Base protocol get SCMI support information + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + */ +FError FScmiBaseInit(FScmi *instance_p) +{ + FError ret; + char name[FSCMI_MAX_STR_SIZE]; + int id; + + /* first get PROTOCOL_VERSION FSCMI_BASE_PROTOCOL_VERSION*/ + ret = FScmiBaseGetVersion(instance_p,&instance_p->revision.version); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + /* FSCMI_BASE_PROTOCOL_ATTRIBUTES */ + ret = FScmiBaseGetAttributes(instance_p,&instance_p->revision.num_protocols,&instance_p->revision.num_agents); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get num_protocols,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + /* FSCMI_BASE_PROTOCOL_DISCOVER_VENDOR and FSCMI_BASE_PROTOCOL_DISCOVER_SUB_VENDOR */ + ret = FScmiBaseGetVendor(instance_p,FALSE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get major_ver,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + ret = FScmiBaseGetVendor(instance_p,TRUE); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get major_ver,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + /* FSCMI_BASE_PROTOCOL_DISCOVER_IMPLEMENTATION_VERSION */ + ret = FScmiBaseGetImplementVersion(instance_p,&instance_p->revision.impl_ver); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get impl_ver,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + /* FSCMI_BASE_PROTOCOL_DISCOVER_LIST_PROTOCOLS */ + ret = FScmiBaseGetImplementList(instance_p,instance_p->protocols_imp); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get vendor_id,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + + instance_p->revision.major_ver = (instance_p->revision.version >> 16); + instance_p->revision.minor_ver = (instance_p->revision.version & 0xffff); + + FSCMI_BASE_INFO("SCMI Protocol v%d.%d '%s:%s' Firmware version 0x%x\n", instance_p->revision.major_ver, + instance_p->revision.minor_ver, + instance_p->revision.vendor_id, + instance_p->revision.sub_vendor_id, + instance_p->revision.impl_ver); + + FSCMI_BASE_INFO("Found %d protocol(s) %d agent(s)\n",instance_p->revision.num_protocols,instance_p->revision.num_agents); + + /* FSCMI_BASE_PROTOCOL_DISCOVER_AGENT */ + for ( id = 0; id < instance_p->revision.num_agents; id++) + { + ret = FScmiBaseGetAgent(instance_p,id,name); + if(ret != FT_SUCCESS) + { + FSCMI_BASE_ERROR("Can't get sub_vendor_id,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + FSCMI_BASE_INFO("Agent %d:%s\n",id,name); + } + + return FT_SUCCESS; +} diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.h new file mode 100644 index 0000000000..1ae4d46f2d --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_base.h @@ -0,0 +1,60 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_base.h + * Date: 2022-12-31 21:38:51 + * LastEditTime: 2022-12-31 21:38:51 + * Description: This file is for base protocol message + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/04 init + */ + + + +#ifndef FSCMI_BASE_PROTOCOL_H +#define FSCMI_BASE_PROTOCOL_H + +#include "ftypes.h" +#include "ferror_code.h" +#include "fparameters.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define FSCMI_BASE_PROTOCOL_VERSION 0x0 +#define FSCMI_BASE_PROTOCOL_ATTRIBUTES 0x1 +#define FSCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES 0x2 +#define FSCMI_BASE_PROTOCOL_DISCOVER_VENDOR 0x3 +#define FSCMI_BASE_PROTOCOL_DISCOVER_SUB_VENDOR 0x4 +#define FSCMI_BASE_PROTOCOL_DISCOVER_IMPLEMENTATION_VERSION 0x5 +#define FSCMI_BASE_PROTOCOL_DISCOVER_LIST_PROTOCOLS 0x6 +#define FSCMI_BASE_PROTOCOL_DISCOVER_AGENT 0x7 +#define FSCMI_BASE_PROTOCOL_NOTIFY_ERRORS 0x8 +#define FSCMI_BASE_PROTOCOL_SET_DEVICE_PERMISSIONS 0x9 +#define FSCMI_BASE_PROTOCOL_SET_PROTOCOL_PERMISSIONS 0xa +#define FSCMI_BASE_PROTOCOL_RESET_AGENT_CONFIGURATION 0xb + +FError FScmiBaseInit(FScmi *instance_p); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.c new file mode 100644 index 0000000000..29620e8fc9 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.c @@ -0,0 +1,543 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_perf.c + * Date: 2023-01-18 15:38:15 + * LastEditTime: 2023-01-18 15:38:17 + * Description:  This file is for performance domain control + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/31 init + */ + +#include "fscmi_perf.h" +#include +#include "fscmi.h" +#include "fscmi_base.h" +#include "fio.h" +#include "fdebug.h" +#include "ftypes.h" +#include "fswap.h" +#include "fkernel.h" +#include "fassert.h" + +#define FSCMI_PERF_DEBUG_TAG "FSCMI_PERF" +#define FSCMI_PERF_ERROR(format, ...) FT_DEBUG_PRINT_E(FSCMI_PERF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_PERF_WARN(format, ...) FT_DEBUG_PRINT_W(FSCMI_PERF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_PERF_INFO(format, ...) FT_DEBUG_PRINT_I(FSCMI_PERF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_PERF_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSCMI_PERF_DEBUG_TAG, format, ##__VA_ARGS__) + +static FError FScmiPerfGetVersion(FScmi *instance_p,u32 *rev_info) +{ + FError ret; + struct FScmiTransferInfo *info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_VERSION_GET, SCMI_PROTOCOL_PERF, 0, sizeof(*rev_info),info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + /* Fill in the obtained parameters */ + *rev_info = FtIn32((uintptr)info->rx.buf); + + return FT_SUCCESS; +} + +static FError FScmiPerfAttributesGet(FScmi *instance_p,struct FScmiPerfInfo *pinfo) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiMsgRespPerfAttributes *attr; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_ATTRIBUTES_GET, SCMI_PROTOCOL_PERF, 0, sizeof(*attr),info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + attr = (struct FScmiMsgRespPerfAttributes *)info->rx.buf; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + u16 flags = attr->flags; + pinfo->num_domains = attr->num_domains; + pinfo->power_scale_mw = POWER_SCALE_IN_MILLIWATT(flags); + pinfo->stats_addr = (u32)attr->stats_addr_low | ((u64)(attr->stats_addr_high) << 32); + pinfo->stats_size = attr->stats_size; + + return FT_SUCCESS; +} + +static FError FScmiPerfDomainAttributesGet(FScmi *instance_p, u32 domain, struct FPerfDomInfo *dom_info) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiMsgRespPerfDomainAttributes *attr; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_DOMAIN_ATTRIBUTES, SCMI_PROTOCOL_PERF, sizeof(domain), sizeof(*attr),info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + *(u32 *)info->tx.buf = domain; + attr = (struct FScmiMsgRespPerfDomainAttributes *)info->rx.buf; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + u32 flags = attr->flags; + + dom_info->set_limits = SUPPORTS_SET_LIMITS(flags); + dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags); + dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags); + dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags); + dom_info->sustained_freq_khz = attr->sustained_freq_khz; + dom_info->sustained_perf_level = attr->sustained_perf_level; + if (!dom_info->sustained_freq_khz || + !dom_info->sustained_perf_level) + /* CPUFreq converts to kHz, hence default 1000 */ + dom_info->mult_factor = 1000; + else + dom_info->mult_factor = + (dom_info->sustained_freq_khz * 1000) / + dom_info->sustained_perf_level; + strlcpy(dom_info->name, attr->name, FSCMI_MAX_STR_SIZE); + + return FT_SUCCESS; +} + +static int opp_cmp_func(const void *opp1, const void *opp2) +{ + const struct FScmiOpp *t1 = opp1, *t2 = opp2; + + return t1->perf_val - t2->perf_val; +} + +static FError FScmiPerfDescribeLevelsGet(FScmi *instance_p, u32 domain, struct FPerfDomInfo *perf_dom) +{ + FError ret; + u32 cnt; + struct FScmiTransferInfo *info; + u32 tot_opp_cnt = 0; + u16 num_returned, num_remaining; + struct FScmiOpp *opp; + struct FScmiMsgPerfDescribeLevels *dom_info; + struct FScmiMsgRespPerfDescribeLevels *level_info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_DESCRIBE_LEVELS, SCMI_PROTOCOL_PERF, sizeof(*dom_info), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + dom_info = (struct FScmiMsgPerfDescribeLevels*)info->tx.buf; + level_info = (struct FScmiMsgRespPerfDescribeLevels *)info->rx.buf; + + do + { + dom_info->domain = domain; + /* Set the number of OPPs to be skipped/already read */ + dom_info->level_index = tot_opp_cnt; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + num_returned = level_info->num_returned; + num_remaining = level_info->num_remaining; + if (tot_opp_cnt + num_returned > FSCMI_MAX_OPPS) + { + FSCMI_PERF_ERROR("No. of OPPs exceeded MAX_OPPS"); + break; + } + + opp = &perf_dom->opp[tot_opp_cnt]; + for (cnt = 0; cnt < num_returned; cnt++, opp++) { + opp->perf_val = level_info->opp[cnt].perf_val; + opp->power = level_info->opp[cnt].power; + opp->trans_latency_us = level_info->opp[cnt].transition_latency_us; + + FSCMI_PERF_INFO("Level %d: %d KHz Power cost%d Latency %dus\n", cnt, opp->perf_val, opp->power, opp->trans_latency_us); + } + + tot_opp_cnt += num_returned; + /* + * check for both returned and remaining to avoid infinite + * loop due to buggy firmware + */ + } while (num_returned && num_remaining); + + perf_dom->opp_count = tot_opp_cnt; + //sort(perf_dom->opp, tot_opp_cnt, sizeof(*opp), opp_cmp_func, NULL); + + return FT_SUCCESS; +} + +static FError FScmiPerfLimitsSet(FScmi *instance_p, u32 domain, u32 max_perf, u32 min_perf) +{ + FASSERT(instance_p != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + struct FScmiTransferInfo *info; + struct FScmiPerfSetLimits *limits; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_LIMITS_SET, SCMI_PROTOCOL_PERF, sizeof(*limits), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + limits = (struct FScmiPerfSetLimits *)info->tx.buf; + limits->domain = domain; + limits->max_level = max_perf; + limits->min_level = min_perf; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + FSCMI_PERF_INFO("FScmiPerfLimitsSet domain:%d max_level:%d KHz, min_level:%d KHz.",limits->domain,limits->max_level,limits->min_level); + //FSCMI_PERF_INFO("FScmiPerfLimitsSet status:%d.",(int)instance_p->info->hdr.status); + return FT_SUCCESS; +} + +static FError FScmiPerfLimitsGet(FScmi *instance_p, u32 domain, u32 *max_perf, u32 *min_perf) +{ + FASSERT(instance_p != NULL); + FASSERT(max_perf != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + s32 status; + struct FScmiTransferInfo *info; + struct FScmiPerfGetLimits *limits; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_LIMITS_GET, SCMI_PROTOCOL_PERF, sizeof(u32), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + *(u32 *)info->tx.buf = domain; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + limits = (struct FScmiPerfGetLimits *)info->rx.buf; + //status = limits->status; + *max_perf = limits->max_level; + *min_perf = limits->min_level; + FSCMI_PERF_INFO("FScmiPerfLimitsGet domain:%d, max_level:%d KHz, min_level:%d KHz.",domain,*max_perf,*min_perf); + return FT_SUCCESS; +} + +static FError FScmiPerfLevelSet(FScmi *instance_p, u32 domain, u32 level, boolean poll) +{ + FASSERT(instance_p != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + struct FScmiTransferInfo *info; + struct FScmiPerfSetLevel *lvl; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_LEVEL_SET, SCMI_PROTOCOL_PERF, sizeof(*lvl), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + info->poll_completion = poll; + lvl = (struct FScmiPerfSetLevel *)info->tx.buf; + lvl->domain = domain; + lvl->level = level; + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + FSCMI_PERF_INFO("FScmiPerfLevelSet domain:%d level:%d KHz.",lvl->domain,lvl->level); + return FT_SUCCESS; +} + +static FError FScmiPerfLevelGet(FScmi *instance_p, u32 domain, u32 *level, boolean poll) +{ + FASSERT(instance_p != NULL); + FASSERT(level != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + struct FScmiTransferInfo *info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_PERF); + if (info == NULL) + { + FSCMI_PERF_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_PERF); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, PERF_LEVEL_GET, SCMI_PROTOCOL_PERF, sizeof(u32), sizeof(u32),info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + info->poll_completion = poll; + *(u32 *)info->tx.buf = domain; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_PERF); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + + *level = *(u32 *)info->rx.buf; + FSCMI_PERF_INFO("FScmiPerfLevelGet domain:%d level:%d KHz.",domain,*level); + return FT_SUCCESS; +} + +/** + * @name: FScmiDvfsFreqSet + * @msg: Dynamic frequency scaling set + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + * @param {u32} domain 性能域id + * @param {u64} freq 频率值Hz,依据初始化获得的level对应的值写入,不支持任意调频 + * @param {boolean} poll 写入模式 + */ +FError FScmiDvfsFreqSet(FScmi *instance_p, u32 domain, u64 freq_Hz, boolean poll) +{ + FASSERT(instance_p != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + struct FScmiPerfInfo *pi = &instance_p->perf; + struct FPerfDomInfo *dom = pi->dom_info + domain; + + ret = FScmiPerfLevelSet(instance_p, domain, freq_Hz / dom->mult_factor, poll); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("FScmiPerfLevelSet error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + return FT_SUCCESS; +} + +/** + * @name: FScmiDvfsFreqGet + * @msg: Dynamic frequency scaling get + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + * @param {u32} domain 性能域id + * @param {u64} *freq 当前性能域的频率值 + * @param {boolean} poll 写入模式 + */ +FError FScmiDvfsFreqGet(FScmi *instance_p, u32 domain, u64 *freq, boolean poll) +{ + FASSERT(instance_p != NULL); + FASSERT(freq != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + FError ret; + u32 level; + struct FScmiPerfInfo *pi = &instance_p->perf; + struct FPerfDomInfo *dom = pi->dom_info + domain; + + ret = FScmiPerfLevelGet(instance_p, domain, &level, poll); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("FScmiPerfLevelGet error ,protocol id is %d",SCMI_PROTOCOL_PERF); + return ret; + } + *freq = level * dom->mult_factor; + return FT_SUCCESS; +} + +u64 FScmiPerfGetOppFreq(FScmi *instance_p,u32 domain,u32 opp_num) +{ + FASSERT(instance_p != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + FASSERT(domain < instance_p->perf.num_domains); + + struct FPerfDomInfo *dom = &instance_p->perf.dom_info[domain]; + + if (opp_num > dom->opp_count) + { + FSCMI_PERF_ERROR("Can't find opp_num,please check."); + return FSCMI_ERROR_REQUEST; + } + + return dom->opp[opp_num].perf_val * dom->mult_factor; +} + +/** + * @name: FScmiPerfInit + * @msg: Performance domain initialization + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + */ +FError FScmiPerfInit(FScmi *instance_p) +{ + FError ret; + struct FScmiPerfInfo *pinfo; + pinfo = &instance_p->perf; + + ret = FScmiPerfGetVersion(instance_p,&instance_p->perf.version); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + instance_p->perf.major_ver = (instance_p->perf.version >> 16); + instance_p->perf.minor_ver = (instance_p->perf.version & 0xffff); + FSCMI_PERF_INFO("Perf Version %d.%d\n",instance_p->perf.major_ver, instance_p->perf.minor_ver); + + ret = FScmiPerfAttributesGet(instance_p, pinfo); + if(ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + + FSCMI_PERF_INFO("SCMI Perf num_domains:%d,power_scale_mw:%d,stats_addr:0x%x,stats_size:0x%x.\n", instance_p->perf.num_domains, + instance_p->perf.power_scale_mw, + instance_p->perf.stats_addr, + instance_p->perf.stats_size); + for (u32 i = 0; i < pinfo->num_domains; i++) + { + struct FPerfDomInfo *dom = pinfo->dom_info + i; + + ret = FScmiPerfDomainAttributesGet(instance_p, i, dom); + if (ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + + ret = FScmiPerfDescribeLevelsGet(instance_p, i, dom); + if (ret != FT_SUCCESS) + { + FSCMI_PERF_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + FSCMI_PERF_INFO("SCMI Perf opp_count:%d,sustained_freq_khz:%d KHz,sustained_perf_level:%d KHz,mult_factor:%d Hz,name:%s.\n", dom->opp_count, + dom->sustained_freq_khz, + dom->sustained_perf_level, + dom->mult_factor, + dom->name); + } + + return FT_SUCCESS; +} diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.h new file mode 100644 index 0000000000..9bd63f3d76 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_perf.h @@ -0,0 +1,114 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_perf.h + * Date: 2022-12-29 16:40:54 + * LastEditTime: 2022-12-29 16:40:55 + * Description:  This file is for performance message struct + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/31 init + */ +#ifndef FSCMI_PERF_H +#define FSCMI_PERF_H + +#include "ftypes.h" +#include "ferror_code.h" +#include "fparameters.h" +#include "fscmi.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum FScmiPerformanceProtocolCmd { + PERF_VERSION_GET = 0x0, + PERF_ATTRIBUTES_GET = 0x1, + PERF_DOMAIN_ATTRIBUTES = 0x3, + PERF_DESCRIBE_LEVELS = 0x4, + PERF_LIMITS_SET = 0x5, + PERF_LIMITS_GET = 0x6, + PERF_LEVEL_SET = 0x7, + PERF_LEVEL_GET = 0x8, + PERF_NOTIFY_LIMITS = 0x9, + PERF_NOTIFY_LEVEL = 0xa, +}; + +struct FScmiMsgRespPerfAttributes { + u16 num_domains; + u16 flags; +#define POWER_SCALE_IN_MILLIWATT(x) ((x) & BIT(0)) + u32 stats_addr_low; + u32 stats_addr_high; + u32 stats_size; +}; + +struct FScmiMsgRespPerfDomainAttributes { + u32 flags; +#define SUPPORTS_SET_LIMITS(x) ((x) & BIT(31)) +#define SUPPORTS_SET_PERF_LVL(x) ((x) & BIT(30)) +#define SUPPORTS_PERF_LIMIT_NOTIFY(x) ((x) & BIT(29)) +#define SUPPORTS_PERF_LEVEL_NOTIFY(x) ((x) & BIT(28)) + u32 rate_limit_us; + u32 sustained_freq_khz; + u32 sustained_perf_level; + u8 name[FSCMI_MAX_STR_SIZE]; +}; + +struct FScmiMsgPerfDescribeLevels { + u32 domain; + u32 level_index; +}; + +struct FScmiPerfSetLimits { + u32 domain; + u32 max_level; + u32 min_level; +}; + +struct FScmiPerfGetLimits { + u32 max_level; + u32 min_level; +}; + +struct FScmiPerfSetLevel { + u32 domain; + u32 level; +}; + +struct FScmiPerfNotifyLevelOrLimits { + u32 domain; + u32 notify_enable; +}; + +struct FScmiMsgRespPerfDescribeLevels { + u16 num_returned; + u16 num_remaining; + struct { + u32 perf_val;/* Performance level value */ + u32 power;/* Power cost */ + u16 transition_latency_us;/* Worst-case transition latency in microseconds to move from any supported performance to the level indicated by this entry in the array */ + u16 reserved; + } opp[0]; +}; + +FError FScmiPerfInit(FScmi *instance_p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.c b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.c new file mode 100644 index 0000000000..1130528b0d --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.c @@ -0,0 +1,365 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_sensors.c + * Date: 2023-01-12 20:52:41 + * LastEditTime: 2023-01-12 20:52:42 + * Description:  This file is for cpu sersor information + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/13 init + */ + +#include "fscmi_sensors.h" +#include +#include "fscmi.h" +#include "fscmi_base.h" +#include "fio.h" +#include "fdebug.h" +#include "fsleep.h" +#include "ftypes.h" +#include "fswap.h" +#include "fkernel.h" +#include "fassert.h" + +#define FSCMI_SENSOR_DEBUG_TAG "FSCMI_SENSOR" +#define FSCMI_SENSOR_ERROR(format, ...) FT_DEBUG_PRINT_E(FSCMI_SENSOR_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_SENSOR_WARN(format, ...) FT_DEBUG_PRINT_W(FSCMI_SENSOR_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_SENSOR_INFO(format, ...) FT_DEBUG_PRINT_I(FSCMI_SENSOR_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSCMI_SENSOR_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSCMI_SENSOR_DEBUG_TAG, format, ##__VA_ARGS__) + +static FError FScmiSensorGetVersion(FScmi *instance_p,u32 *rev_info) +{ + FError ret; + struct FScmiTransferInfo *info; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, SENSOR_VERSION_GET, SCMI_PROTOCOL_SENSOR, 0, sizeof(*rev_info),info->tx.buf); + + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + /* Fill in the obtained parameters */ + *rev_info = FtIn32((uintptr)info->rx.buf); + + return FT_SUCCESS; +} + +static FError FScmiSensorAttributesGet(FScmi *instance_p,struct FScmiSensorsInfo *si) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FScmiMsgRespSensorAttributes *attr; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + ret = FScmiMessageInit(instance_p, SENSOR_ATTRIBUTES_GET,SCMI_PROTOCOL_SENSOR, 0, sizeof(*attr), info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + /* Fill in the obtained parameters */ + attr = (struct FScmiMsgRespSensorAttributes *)info->rx.buf; + + si->num_sensors = (int)attr->num_sensors; + si->max_requests = (int)attr->max_requests; + si->reg_addr = (u32)attr->reg_addr_low | ((u64)(attr->reg_addr_high)) << 32; + si->reg_size = (u32)(attr->reg_size); + + return FT_SUCCESS; +} + +static FError FScmiSensorDescriptionGet(FScmi *instance_p,struct FScmiSensorsInfo *si) +{ + int ret, cnt; + u32 desc_index = 0; + u16 num_returned, num_remaining; + struct FScmiTransferInfo *info; + struct FScmiMsgRespSensorDescription *buf; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + ret = FScmiMessageInit(instance_p, SENSOR_DESCRIPTION_GET, SCMI_PROTOCOL_SENSOR, sizeof(u32), 0, info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + buf = (struct FScmiMsgRespSensorDescription *)info->rx.buf; + + FSCMI_SENSOR_INFO("DescriptionGet:num_returned:%d,num_remaining:%d.\n",buf->num_returned,buf->num_remaining); + do { + /* Set the number of sensors to be skipped/already read */ + *(u32 *)info->tx.buf = desc_index; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + num_returned = (u16)(buf->num_returned); + num_remaining = (u16)(buf->num_remaining); + + if (desc_index + (u32)num_returned > si->num_sensors) { + FSCMI_SENSOR_ERROR("No. of sensors can't exceed:%d+%d > %d", desc_index, num_returned, si->num_sensors); + break; + } + + for (cnt = 0; cnt < num_returned; cnt++) { + u32 attrh; + struct FScmiSensorInfo *s; + + attrh = (u32)(buf->desc[cnt].attributes_high); + s = &si->sensor_info[desc_index + cnt]; + s->id = (u32)(buf->desc[cnt].id); + s->type = SENSOR_TYPE(attrh); + strlcpy(s->name, buf->desc[cnt].name, FSCMI_MAX_STR_SIZE); + FSCMI_SENSOR_INFO("DescriptionGet:id:%d,type:%d,name:%s.\n",s->id,s->type,s->name); + } + + desc_index += num_returned; + /* + * check for both returned and remaining to avoid infinite + * loop due to buggy firmware + */ + } while (num_returned && num_remaining); + return ret; +} + +static int FScmiSensorsTripPointSet(FScmi *instance_p,u32 sensor_id, u8 trip_id, u64 trip_value) +{ + FError ret; + u32 evt_cntl = SENSOR_TP_BOTH; + struct FScmiTransferInfo *info; + struct FScmiMsgSetSensorTripPoint *trip; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, SENSOR_TRIP_POINT_SET, SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + trip = (struct FScmiMsgSetSensorTripPoint *)info->tx.buf; + trip->id = sensor_id; + trip->event_control = evt_cntl; + trip->value_low = trip_value & 0xffffffff; + trip->value_high = trip_value >> 32; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + return FT_SUCCESS; +} +static FError FScmiSensorsConfigurationSet(FScmi *instance_p,u32 sensor_id) +{ + FError ret; + u32 evt_cntl = BIT(0); + struct FScmiTransferInfo *info; + struct FScmiMsgSetSensorConfig *cfg; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, SENSOR_CONFIG_SET, SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0,info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + cfg = (struct FScmiMsgSetSensorConfig *)info->tx.buf; + cfg->id = sensor_id; + cfg->event_control = evt_cntl; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + return FT_SUCCESS; +} + +static FError FScmiSensorsReadingGet(FScmi *instance_p,u32 sensor_id, boolean async, s64 *value) +{ + FError ret; + struct FScmiTransferInfo *info; + struct FcmiMsgSensorReadingGet *sensor; + + info = FScmiGetInfo(instance_p, SCMI_PROTOCOL_SENSOR); + if (info == NULL) + { + FSCMI_SENSOR_ERROR("Info data structure not found ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return FSCMI_ERROR_NULL_POINTER; + } + + /* Prepare hdr packaging */ + ret = FScmiMessageInit(instance_p, SENSOR_READING_GET, SCMI_PROTOCOL_SENSOR, sizeof(*sensor), sizeof(u64),info->tx.buf); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Prepare hdr packaging is error ,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + sensor = (struct FcmiMsgSensorReadingGet *)info->tx.buf; + sensor->id = sensor_id; + sensor->flags = async ? SENSOR_READ_ASYNC:0; + + ret = FScmiDoTransport(instance_p, info, SCMI_PROTOCOL_SENSOR); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Transport package error,protocol id is %d",SCMI_PROTOCOL_SENSOR); + return ret; + } + + /* Fill in the obtained parameters */ + u32 *pval = (u32 *)info->rx.buf; + *value = *pval; + *value |= (s64)(*(pval +1)) << 32; + return FT_SUCCESS; +} + +/** + * @name: FScmiSensorGetTemp + * @msg: + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + * @param {u32} sensor_id 传感器ID,可以在初始化后获取 + * @param {s64} *temp 获取对应ID传感器的温度 + */ +FError FScmiSensorGetTemp(FScmi *instance_p, u32 sensor_id,s64 *temp) +{ + FASSERT(instance_p != NULL); + FASSERT(temp != NULL); + FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY); + + FError ret; + + if(instance_p->sensors.num_sensors > 0 && instance_p->sensors.num_sensors > sensor_id) + { + if (instance_p->sensors.sensor_info[sensor_id].type == DEGRESS_C) + { + FScmiSensorsReadingGet(instance_p, sensor_id, FALSE, temp); + FSCMI_SENSOR_INFO("FScmiSensorsReadingGet type DEGRESS_C value: %d `C.",*temp); + } + } + else + { + FSCMI_SENSOR_ERROR("Can't find sensor,please running function FScmiSensorInit first."); + } + return FT_SUCCESS; +} + +/** + * @name: FScmiSensorInit + * @msg: Sensor initialization + * @return {FError} 返回值 + * @param {FScmi} *instance_p scmi协议实例 + */ +FError FScmiSensorInit(FScmi *instance_p) +{ + u32 version; + FError ret; + struct FScmiSensorsInfo *sinfo; + sinfo = &instance_p->sensors; + + ret = FScmiSensorGetVersion(instance_p,&instance_p->sensors.version); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + instance_p->sensors.major_ver = (instance_p->sensors.version >> 16); + instance_p->sensors.minor_ver = (instance_p->sensors.version & 0xffff); + FSCMI_SENSOR_INFO("Sensor Version %d.%d\n",instance_p->sensors.major_ver, instance_p->sensors.minor_ver); + + ret = FScmiSensorAttributesGet(instance_p, sinfo); + if(ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + + FSCMI_SENSOR_INFO("SCMI Sensors num:%d,requests:%d,reg_addr:0x%x,reg_size:0x%x.\n", instance_p->sensors.num_sensors, + instance_p->sensors.max_requests, + instance_p->sensors.reg_addr, + instance_p->sensors.reg_size); + ret = FScmiSensorDescriptionGet(instance_p, sinfo); + if (ret != FT_SUCCESS) + { + FSCMI_SENSOR_ERROR("Can't get version,please check mem_address or chan_id.Error code:0x%x.",ret); + return FSCMI_ERROR_REQUEST; + } + return FT_SUCCESS; +} + diff --git a/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.h b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.h new file mode 100644 index 0000000000..ee0edc3928 --- /dev/null +++ b/bsp/phytium/libraries/standalone/drivers/scmi/fscmi_mhu/fscmi_sensors.h @@ -0,0 +1,114 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fscmi_sensors.h + * Date: 2023-01-12 20:53:01 + * LastEditTime: 2023-01-12 20:53:01 + * Description:  This file is for cpu sensor message struct + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2023/01/13 init + */ + +#ifndef FSCMI_SENSORS_PROTOCOL_H +#define FSCMI_SENSORS_PROTOCOL_H + +#include "ftypes.h" +#include "ferror_code.h" +#include "fparameters.h" +#include "fscmi.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Sensor Type Enumerations */ +enum FScmiSensorType +{ + NONE=0x0, + UNSPECIFIED, + DEGRESS_C, + DEGRESS_F, + DEGRESS_K, +}; + +enum FScmiSensorProtocolCmd { + SENSOR_VERSION_GET = 0x0, + SENSOR_ATTRIBUTES_GET = 0x1, + SENSOR_DESCRIPTION_GET = 0x3, + SENSOR_CONFIG_SET = 0x4, + SENSOR_TRIP_POINT_SET = 0x5, + SENSOR_READING_GET = 0x6, +}; + +struct FScmiMsgRespSensorAttributes { + u16 num_sensors; + u8 max_requests; + u8 reserved; + u32 reg_addr_low; + u32 reg_addr_high; + u32 reg_size; +}; + +struct FScmiMsgRespSensorDescription { + u16 num_returned; + u16 num_remaining; + struct { + u32 id; + u32 attributes_low; +#define SUPPORTS_ASYNC_READ(x) ((x) & BIT(31)) +#define NUM_TRIP_POINTS(x) ((x) & 0xff) + u32 attributes_high; +#define SENSOR_TYPE(x) ((x) & 0xff) +#define SENSOR_SCALE(x) (((x) >> 11) & 0x1f) +#define SENSOR_UPDATE_SCALE(x) (((x) >> 22) & 0x1f) +#define SENSOR_UPDATE_BASE(x) (((x) >> 27) & 0x1f) + u8 name[FSCMI_MAX_STR_SIZE]; + } desc[0]; +}; + +struct FScmiMsgSetSensorConfig { + u32 id; + u32 event_control; +}; + +struct FScmiMsgSetSensorTripPoint { + u32 id; + u32 event_control; +#define SENSOR_TP_EVENT_MASK (0x3) +#define SENSOR_TP_DISABLED 0x0 +#define SENSOR_TP_POSITIVE 0x1 +#define SENSOR_TP_NEGATIVE 0x2 +#define SENSOR_TP_BOTH 0x3 +#define SENSOR_TP_ID(x) (((x) & 0xff) << 4) + u32 value_low; + u32 value_high; +}; + +struct FcmiMsgSensorReadingGet { + u32 id; + u32 flags; +#define SENSOR_READ_ASYNC BIT(0) +}; + +FError FScmiSensorInit(FScmi *instance_p); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/bsp/phytium/libraries/standalone/drivers/serial/Kconfig b/bsp/phytium/libraries/standalone/drivers/serial/Kconfig index d01d698f98..e84c41301c 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/serial/Kconfig @@ -4,7 +4,7 @@ menu "Usart Configuration" bool prompt "Use Pl011 uart" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.c index f7023b1b2f..6aabf5e803 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.c @@ -12,17 +12,18 @@ * * * FilePath: fpl011.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:07:24 - * Description:  This files is for uart functions + * Description:  This file is for uart functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 fix bug */ /***************************** Include Files ********************************/ - #include "fpl011.h" #include "fio.h" #include "ferror_code.h" @@ -136,7 +137,7 @@ static void FPl011StubHandler(void *args, u32 event, /** * @name: FPl011SendBuffer - * @msg: send data buffer through uart + * @msg: send data buffer through uart,if you close FIFO and open interrupt,recommend use FPl011BlockSend * @return {*} * @param uart_p */ @@ -156,16 +157,14 @@ u32 FPl011SendBuffer(FPl011 *uart_p) * Otherwise put bytes into the TX FIFO unil it is full, or all of the * data has been put into the FIFO. */ - while ((!FUART_ISTRANSMITFULL(uart_p->config.base_address)) && (uart_p->send_buffer.remaining_bytes > sent_count)) + while ((!FUART_ISTRANSMITFULL(uart_p->config.base_address)) && (uart_p->send_buffer.remaining_bytes > 0)) { - FUART_WRITEREG32(uart_p->config.base_address, FPL011DR_OFFSET, (u32)uart_p->send_buffer.byte_p[sent_count]); - sent_count++; - } - /* Update the buffer to reflect the bytes that were sent from it */ - uart_p->send_buffer.byte_p += sent_count; - uart_p->send_buffer.remaining_bytes -= sent_count; + sent_count = uart_p->send_buffer.requested_bytes - uart_p->send_buffer.remaining_bytes; + uart_p->send_buffer.remaining_bytes--; - return sent_count; + FUART_WRITEREG32(uart_p->config.base_address, FPL011DR_OFFSET, (u32)uart_p->send_buffer.byte_p[sent_count]); + } + return uart_p->send_buffer.requested_bytes - uart_p->send_buffer.remaining_bytes; } /** @@ -203,7 +202,7 @@ u32 FPl011ReceiveBuffer(FPl011 *uart_p) u32 event_data; u32 byte_value; - while ((received_count < uart_p->receive_buffer.remaining_bytes) && !FUART_ISRECEIVEDATA(uart_p->config.base_address)) + while ((received_count < uart_p->receive_buffer.remaining_bytes) && !FUART_RECEIVEDATAEMPTY(uart_p->config.base_address)) { byte_value = FUART_READREG32(uart_p->config.base_address, FPL011DR_OFFSET); diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.h b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.h index 349b6a352e..354743d460 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.h +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011.h @@ -12,17 +12,24 @@ * * * FilePath: fpl011.h - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:07:38 - * Description:  This files is for uart functions + * Description:  This file is for uart functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 fix bug */ -#ifndef BSP_DRIVERS_SERIAL_PL011_UART_H -#define BSP_DRIVERS_SERIAL_PL011_UART_H +#ifndef FPL011_H +#define FPL011_H + +#include "ftypes.h" +#include "fassert.h" +#include "fpl011_hw.h" +#include "sdkconfig.h" #ifdef __cplusplus @@ -30,12 +37,6 @@ extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "ftypes.h" -#include "fassert.h" -#include "fpl011_hw.h" -#include "sdkconfig.h" /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -93,7 +94,7 @@ extern "C" #define FPL011_EVENT_RECV_ERROR 4U /* A receive error detected */ #define FPL011_EVENT_MODEM 5U /* Modem status changed */ #define FPL011_EVENT_PARE_FRAME_BRKE 6U /* A receive parity, frame, break \ - * error detected */ +* error detected */ #define FPL011_EVENT_RECV_ORERR 7U /* A receive overrun error detected */ @@ -114,7 +115,7 @@ typedef struct typedef struct { u32 instance_id; /* Id of device*/ - u32 base_address; + uintptr base_address; u32 ref_clock_hz; u32 irq_num; u32 baudrate; diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_g.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_g.c index 2717101988..87483e4e9d 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_g.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_g.c @@ -12,13 +12,15 @@ * * * FilePath: fpl011_g.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:05:41 - * Description:  This files is for uart config + * Description:  This file is for uart static configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 add configs */ /***************************** Include Files *********************************/ @@ -53,6 +55,7 @@ const FPl011Config FPl011ConfigTable[FUART_NUM] = .irq_num = FUART1_IRQ_NUM, .baudrate = 115200 }, +#ifndef TARDIGRADE { .instance_id = FUART2_ID, .base_address = FUART2_BASE_ADDR, @@ -67,4 +70,6 @@ const FPl011Config FPl011ConfigTable[FUART_NUM] = .irq_num = FUART3_IRQ_NUM, .baudrate = 115200 } +#endif // !TARDIGRADE + }; diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.c index 9b468f2439..83bdfa6068 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.c @@ -12,13 +12,15 @@ * * * FilePath: fpl011_hw.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:05:56 - * Description:  This files is for uart register function + * Description:  This file is for uart register function * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 add file head */ /***************************** Include Files *********************************/ @@ -43,7 +45,7 @@ * @param addr contains the base address of the device. * @param Byte contains the byte to be sent. */ -void FPl011SendByte(u32 addr, u8 byte) +void FPl011SendByte(uintptr addr, u8 byte) { while (FUART_ISTRANSMITFULL(addr)) @@ -59,11 +61,11 @@ void FPl011SendByte(u32 addr, u8 byte) * and blocks until a byte has received. * @param addr contains the base address of the device. */ -u8 FPl011RecvByte(u32 addr) +u8 FPl011RecvByte(uintptr addr) { u32 recieved_byte; - while (FUART_ISRECEIVEDATA(addr)) + while (FUART_RECEIVEDATAEMPTY(addr)) { ; } diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.h b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.h index cec10c1fa0..1dcb5280c1 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_hw.h @@ -12,26 +12,31 @@ * * * FilePath: fpl011_hw.h - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:06:10 - * Description:  This files is for definition of uart register + * Description:  This file is for definition of uart register * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 modified some defines */ -#ifndef BSP_DRIVERS_SERIAL_PL011_UART_HW_H -#define BSP_DRIVERS_SERIAL_PL011_UART_HW_H +#ifndef FPL011_HW_H +#define FPL011_HW_H + +#include "ftypes.h" +#include "fassert.h" +#include "fio.h" + #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fassert.h" -#include "fio.h" + /************************** Constant Definitions *****************************/ @@ -218,13 +223,13 @@ extern "C" #define FUART_WRITEREG32(addr, reg_offset, reg_value) FtOut32(addr + (u32)reg_offset, (u32)reg_value) /** - * @name: FUART_ISRECEIVEDATA + * @name: FUART_RECEIVEDATAEMPTY * @msg: Used to confirm whether data has been received * @param addr contains the base address of the device. - * @return {bool} true 是存在数据 , false 是不存在数据 + * @return {bool} true 是不存在数据 , false 是存在数据 * */ -#define FUART_ISRECEIVEDATA(addr) (FtIn32(addr + FPL011FTR_OFFSET) & FPL011FTR_RXFE) +#define FUART_RECEIVEDATAEMPTY(addr) (FtIn32(addr + FPL011FTR_OFFSET) & FPL011FTR_RXFE) /** * @name: FUART_ISTRANSMITFULL @@ -245,8 +250,8 @@ extern "C" /************************** Function Prototypes ******************************/ -void FPl011SendByte(u32 addr, u8 byte); -u8 FPl011RecvByte(u32 addr); +void FPl011SendByte(uintptr addr, u8 byte); +u8 FPl011RecvByte(uintptr addr); #ifdef __cplusplus } diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_intr.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_intr.c index de69f982ae..6a263dd656 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_intr.c @@ -12,13 +12,15 @@ * * * FilePath: fpl011_intr.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:06:30 - * Description:  This files is for uart irq functions + * Description:  This file is for uart irq functions * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 fix bugs */ @@ -187,7 +189,6 @@ static void FPl011ReceiveDataHandler(FPl011 *uart_p) { (void)FPl011ReceiveBuffer(uart_p); } - if ((u32)0 == uart_p->receive_buffer.remaining_bytes) { if (uart_p->handler) @@ -205,7 +206,6 @@ static void FPl011ReceiveTimeoutHandler(FPl011 *uart_p) { (void)FPl011ReceiveBuffer(uart_p); } - if ((u32)0 == uart_p->receive_buffer.remaining_bytes) { event = FPL011_EVENT_RECV_TOUT; diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_options.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_options.c index 4e4584d077..d94df0db0d 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_options.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_options.c @@ -12,13 +12,15 @@ * * * FilePath: fpl011_options.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:06:45 - * Description:  This files is for uart option setting + * Description:  This file is for uart option setting * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 fix bug */ @@ -108,7 +110,9 @@ void FPl011SetSpecificOptions(FPl011 *uart_p, u32 options) for (index = 0; index < FUART_NUM_OPITIONS; index++) { if ((options & option_table[index].option) == (u32)(0)) + { continue; + } reg_value = FUART_READREG32(uart_p->config.base_address, option_table[index].register_offset); /* set specific options */ @@ -118,7 +122,7 @@ void FPl011SetSpecificOptions(FPl011 *uart_p, u32 options) } /** - * @name: FPl011SetSpecificOptions + * @name: FPl011ClearSpecificOptions * @msg: Clear the options for the specified driver instance. * @param uart_p is a pointer to the uart instance. * @param options contains the options to be set which are bit masks @@ -133,7 +137,9 @@ void FPl011ClearSpecificOptions(FPl011 *uart_p, u32 options) for (index = 0; index < FUART_NUM_OPITIONS; index++) { if ((options & option_table[index].option) == (u32)(0)) + { continue; + } reg_value = FUART_READREG32(uart_p->config.base_address, option_table[index].register_offset); /* remove specific options */ @@ -166,8 +172,8 @@ FError FPl011SetDataFormat(FPl011 *uart_p, FPl011Format *format_p) config_p = &uart_p->config; if ((format_p->data_bits > ((u32)(FPL011_FORMAT_WORDLENGTH_8BIT))) || - (format_p->parity > ((u32)(FPL011_FORMAT_PARITY_MASK))) || - (format_p->stopbits > ((u32)(FPL011_FORMAT_PARITY_MASK))) + (format_p->parity > ((u32)(FPL011_FORMAT_PARITY_MASK))) || + (format_p->stopbits > ((u32)(FPL011_FORMAT_PARITY_MASK))) ) { return FPL011_ERROR_PARAM ; @@ -299,7 +305,7 @@ void FPl011SetTxFifoThreadHold(FPl011 *uart_p, u8 trigger_level) fifo_trig_reg = FUART_READREG32(config_p->base_address, FPL011IFLS_OFFSET); - fifo_trig_reg &= ~(FPL011IFLS_TXIFLSEL_MASK | FPL011IFLS_RXIFLSEL_MASK); + fifo_trig_reg &= ~(FPL011IFLS_TXIFLSEL_MASK); fifo_trig_reg |= (u32)trigger_level; @@ -467,14 +473,14 @@ void FPl011SetOperMode(FPl011 *uart_p, u8 operation_mode) switch (operation_mode) { - case FPL011_OPER_MODE_NORMAL: - ctrl_reg |= FPL011CR_MODE_NORMAL; - break; - case FPL011_OPER_MODE_LOCAL_LOOP: - ctrl_reg |= FPL011CR_LBE; - break; - default: - break; + case FPL011_OPER_MODE_NORMAL: + ctrl_reg |= FPL011CR_MODE_NORMAL; + break; + case FPL011_OPER_MODE_LOCAL_LOOP: + ctrl_reg |= FPL011CR_LBE; + break; + default: + break; } /* Setup the Control Register with the passed argument.*/ diff --git a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_sinit.c b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_sinit.c index ae9f4834e7..382c9ace4b 100644 --- a/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/serial/fpl011/fpl011_sinit.c @@ -12,13 +12,15 @@ * * * FilePath: fpl011_sinit.c - * Date: 2022-02-10 14:53:42 + * Date: 2021-11-02 14:53:42 * LastEditTime: 2022-02-18 09:07:00 - * Description:  This files is for uart static init + * Description:  This file is for uart static init * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/11/2 first commit + * 1.1 liushengming 2022/02/18 add file head */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/spi/Kconfig b/bsp/phytium/libraries/standalone/drivers/spi/Kconfig index 2133ced9fb..1d17ec511c 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/spi/Kconfig @@ -4,8 +4,7 @@ config USE_FSPIM prompt "Use FSPIM" default n depends on USE_SPI - depends on TARGET_F2000_4 || TARGET_D2000 || TARGET_E2000S || TARGET_E2000D || TARGET_E2000Q help Select FSPIM driver component - - + + diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.c index b2694483ad..0fc6f4bc6e 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.c @@ -14,14 +14,15 @@ * FilePath: fspim.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:32 - * Description:  This files is for spim api implementation + * Description:  This file is for spim api implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode - * 1.2 zhugengyu 2022-5-13 support spi dma + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode + * 1.2 zhugengyu 2022/5/13 support spi dma + * 1.3 liqiaozhong 2022/12/30 add check func and spim option func */ @@ -52,14 +53,14 @@ FError FSpimReset(FSpim *instance_p); /************************** Variable Definitions *****************************/ static const char *FSPIM_ERROR_CODE_MSG[FSPIM_NUM_OF_ERR_CODE] = { - "FSPIM_SUCCESS : fspim success", - "FSPIM_ERR_INVAL_STATE : fspim invalid state", - "FSPIM_ERR_NOT_READY : fspim driver not ready", - "FSPIM_ERR_INVAL_PARAM : fspim invalid input parameters", - "FSPIM_ERR_BUS_BUSY : fspim bus is busy", - "FSPIM_ERR_NOT_SUPPORT : fspim not support operation", - "FSPIM_ERR_TIMEOUT : fspim wait timeout", - "FSPIM_ERR_TRANS_FAIL : fspim data transfer failed", + "FSPIM_SUCCESS : The fspim was successful", + "FSPIM_ERR_INVAL_STATE : The fspim invalid state", + "FSPIM_ERR_NOT_READY : The fspim driver is not ready", + "FSPIM_ERR_INVAL_PARAM : The fspim input parameter is invalid", + "FSPIM_ERR_BUS_BUSY : The fspim bus is busy", + "FSPIM_ERR_NOT_SUPPORT : Operations are not supported by fspim", + "FSPIM_ERR_TIMEOUT : The fspim waits for a timeout", + "FSPIM_ERR_TRANS_FAIL : The fspim data transmission failed", }; @@ -92,7 +93,7 @@ FError FSpimCfgInitialize(FSpim *instance_p, const FSpimConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == instance_p->is_ready) { - FSPIM_WARN("device is already initialized!!!"); + FSPIM_WARN("The device has been initialized!!!"); } /* @@ -103,9 +104,7 @@ FError FSpimCfgInitialize(FSpim *instance_p, const FSpimConfig *input_config_p) FSpimDeInitialize(instance_p); instance_p->config = *input_config_p; - /* - * Reset the device. - */ + /* Reset the device. */ ret = FSpimReset(instance_p); if (FSPIM_SUCCESS == ret) { @@ -133,7 +132,7 @@ void FSpimDeInitialize(FSpim *instance_p) /** * @name: FSpimReset - * @msg: 重置FSPIM控制器 + * @msg: Reset FSPIM controller * @return {FError} FSPIM_SUCCESS表示重置成功,其它返回值表示重置失败 * @param {FSpim} *instance_p */ @@ -167,7 +166,7 @@ FError FSpimReset(FSpim *instance_p) /* 选择串行时钟极性和相位 */ FSpimSetCpha(base_addr, instance_p->config.cpha); FSpimSetCpol(base_addr, instance_p->config.cpol); - + /* 设置传输模式 */ FSpimSetTransMode(base_addr, FSPIM_TRANS_MODE_RX_TX); @@ -183,14 +182,14 @@ FError FSpimReset(FSpim *instance_p) { fifo = FSpimGetTxFifoDepth(base_addr); instance_p->tx_fifo_len = ((fifo == 1) ? 0 : fifo); - FSPIM_INFO("fifo depth %d tx_fifo_len %d", fifo, instance_p->tx_fifo_len); + FSPIM_INFO("The fifo depth is %d ,tx effective length bits %d", fifo, instance_p->tx_fifo_len); } if (0 == instance_p->rx_fifo_len) { fifo = FSpimGetRxFifoDepth(base_addr); instance_p->rx_fifo_len = ((fifo == 1) ? 0 : fifo); - FSPIM_INFO("fifo depth %d tx_fifo_len %d", fifo, instance_p->tx_fifo_len); + FSPIM_INFO("The fifo depth is %d ,rx effective length bits %d", fifo, instance_p->rx_fifo_len); } FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_CR_OFFSET, 0x0); /* disable ddma */ @@ -221,16 +220,129 @@ FError FSpimReset(FSpim *instance_p) ret = FSpimSetSpeed(base_addr, instance_p->config.max_freq_hz); if (FSPIM_SUCCESS != ret) + { return ret; + } FSPIM_WRITE_REG32(base_addr, FSPIM_RX_SAMPLE_DLY_OFFSET, FSPIM_DEFAULT_RSD); - /* 使能SPI控制器 */ - FSpimSetEnable(base_addr, TRUE); - return ret; } +/* + * @name: FSpimSetOption + * @msg: Give user a way to set speed and polarity etc. + * @param {FSpim} *instance_p FSPIM驱动控制数据 + * @param {u32} option FSPIM操作标识数 + * @param {u32} value FSPIM用户自定参数 + * @return 驱动初始化的错误码信息,FSPIM_SUCCESS 表示设置成功,其它返回值表示设置失败 + */ +FError FSpimSetOption(FSpim *instance_p, u32 option, u32 value) +{ + FASSERT(instance_p); + uintptr base_addr = instance_p->config.base_addr; + FError ret = FSPIM_SUCCESS; + boolean enabled = FSpimGetEnable(base_addr); + + if (FT_COMPONENT_IS_READY != instance_p->is_ready) + { + FSPIM_ERROR("The device is not initialized!!!"); + return FSPIM_ERR_NOT_READY; + } + + FSpimSetEnable(base_addr, FALSE); + + if (option == FSPIM_CPOLTYPE_OPTION) + { + if (value == FSPIM_CPOL_HIGH || value == FSPIM_CPOL_LOW) + { + FSpimSetCpol(base_addr, value); + instance_p->config.cpol = value; + FSPIM_INFO("Set cpol to %d", value); + } + else + { + FSPIM_ERROR("Input error, CPOL value should be 0 or 1."); + return FSPIM_ERR_INVAL_PARAM; + } + } + + if (option == FSPIM_CPHATYPE_OPTION) + { + if (value == FSPIM_CPHA_2_EDGE || value == FSPIM_CPHA_1_EDGE) + { + FSpimSetCpha(base_addr, value); + instance_p->config.cpha = value; + FSPIM_INFO("Set cpha to %d", value); + } + else + { + FSPIM_ERROR("Input error, CPHA value should be 0 or 1."); + return FSPIM_ERR_INVAL_PARAM; + } + } + + if (option == FSPIM_FREQUENCY_OPTION) + { + if (value <= (FSPI_CLK_FREQ_HZ / FSPIM_BAUD_R_SCKDV_MIN)) + { + ret = FSpimSetSpeed(base_addr, value); + if (FSPIM_SUCCESS != ret) + { + return ret; + } + instance_p->config.max_freq_hz = value; + FSPIM_INFO("Set spim freqency to %d", value); + } + else + { + FSPIM_ERROR("Input error, spim freqency value should be less than 24M."); + return FSPIM_ERR_INVAL_PARAM; + } + } + + if (enabled) + { + FSpimSetEnable(base_addr, TRUE); + } + + return ret; +} + +/* + * @name: FSpimGetOption + * @msg: Give user a way to get speed and polarity etc. + * @param {FSpim} *instance_p FSPIM驱动控制数据 + * @param {u32} option FSPIM操作标识数 + * @return {u32} 获取到的参数值 + */ +u32 FSpimGetOption(FSpim *instance_p, u32 option) +{ + FASSERT(instance_p); + uintptr base_addr = instance_p->config.base_addr; + u32 value; + + if (option == FSPIM_CPOLTYPE_OPTION) + { + value = FSpimGetCpol(base_addr); + FSPIM_INFO("Get cpol value: %d", value); + return value; + } + + if (option == FSPIM_CPHATYPE_OPTION) + { + value = FSpimGetCpha(base_addr); + FSPIM_INFO("Get cpha value: %d", value); + return value; + } + + if (option == FSPIM_FREQUENCY_OPTION) + { + value = FSpimGetSpeed(base_addr); + FSPIM_INFO("Get freq_clock value: 0x%x, %d", value, value); + return value; + } +} /** * @name: FSpimGetTxRound * @msg: 计算当前FIFO支持的发送字节数 @@ -393,7 +505,7 @@ FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSPIM_ERROR("device is already initialized!!!"); + FSPIM_ERROR("The device is not initialized!!!"); return FSPIM_ERR_NOT_READY; } @@ -406,11 +518,17 @@ FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; if (tx_buf && rx_buf) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } else if (rx_buf) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + } else + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } FSpimSetCtrlR0(base_addr, reg_val); @@ -439,8 +557,8 @@ FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf /** * @name: FSpimTransferByInterrupt - * @msg: 先发送后接收数据 (中断处理),利用Fifo进行处理 - * @return {FError} FSPIM_SUCCESS表示处理成功,其它返回值表示处理失败 + * @msg: 配置并打开spim中断传输,利用Fifo进行处理 + * @return {FError} FSPIM_SUCCESS表示成功打开中断,其它返回值表示失败 * @param {FSpim} *instance_p 驱动控制数据 * @param {void} *tx_buf 写缓冲区 * @param {void} *rx_buf 读缓冲区 @@ -456,7 +574,7 @@ FError FSpimTransferByInterrupt(FSpim *instance_p, const void *tx_buf, void *rx_ if (FT_COMPONENT_IS_READY != instance_p->is_ready) { - FSPIM_ERROR("device is already initialized!!!"); + FSPIM_ERROR("The device is not initialized!!!"); return FSPIM_ERR_NOT_READY; } @@ -469,11 +587,17 @@ FError FSpimTransferByInterrupt(FSpim *instance_p, const void *tx_buf, void *rx_ reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; if (tx_buf && rx_buf) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } else if (rx_buf) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + } else + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } FSpimSetCtrlR0(base_addr, reg_val); @@ -495,7 +619,7 @@ FError FSpimTransferByInterrupt(FSpim *instance_p, const void *tx_buf, void *rx_ return FSPIM_SUCCESS; } -#ifdef FSPIM_VERSION_2 /* E2000 */ +#if defined(FSPIM_VERSION_2) /* E2000 */ /** * @name: FSpimTransferDMA @@ -527,11 +651,17 @@ FError FSpimTransferDMA(FSpim *instance_p, boolean tx, boolean rx) reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; if (tx && rx) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } else if (rx) + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + } else + { reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } FSpimSetCtrlR0(base_addr, reg_val); @@ -542,14 +672,22 @@ FError FSpimTransferDMA(FSpim *instance_p, boolean tx, boolean rx) /* enable DMA tx / rx */ reg_val = FSPIM_READ_REG32(base_addr, FSPIM_DMA_CR_OFFSET); if (tx) + { reg_val |= FSPIM_DMA_CR_TDMAE; + } else + { reg_val &= ~FSPIM_DMA_CR_TDMAE; + } if (rx) + { reg_val |= FSPIM_DMA_CR_RDMAE; + } else + { reg_val &= ~FSPIM_DMA_CR_RDMAE; + } FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_CR_OFFSET, reg_val); FSpimSelSlaveDev(base_addr, instance_p->config.slave_dev_id); diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.h b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.h index cb3ffb346e..7783ceb520 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.h +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim.h @@ -14,14 +14,15 @@ * FilePath: fspim.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:38 - * Description:  This files is for + * Description:  This file is for providing spim basic api func and predefined variables. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode - * 1.2 zhugengyu 2022-5-13 support spi dma + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode + * 1.2 zhugengyu 2022/5/13 support spi dma + * 1.3 liqiaozhong 2022/12/30 add check func and spim option func */ @@ -34,7 +35,7 @@ extern "C" #endif /***************************** Include Files *********************************/ - +#include "fparameters.h" #include "ftypes.h" #include "ferror_code.h" #include "fassert.h" @@ -52,10 +53,15 @@ extern "C" #define FSPIM_ERR_TRANS_FAIL FT_MAKE_ERRCODE(ErrModBsp, ErrBspSpi, 6) #define FSPIM_ERR_DMA_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrBspSpi, 6) -#if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) -#define FSPIM_VERSION_1 /* 用于FT2000/4和D2000平台的SPIM */ +#define FSPIM_CPOLTYPE_OPTION 0 +#define FSPIM_CPHATYPE_OPTION 1 +#define FSPIM_FREQUENCY_OPTION 2 + +#if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) || defined(TARDIGRADE) +#define FSPIM_VERSION_1 /* SPIM for FT2000/4 and D2000 */ #elif defined(CONFIG_TARGET_E2000) -#define FSPIM_VERSION_2 /* 用于E2000平台的SPIM */ +#define FSPIM_VERSION_2 /* SPIM for E2000 */ + #else #error "Invalid target board !!!" #endif @@ -64,6 +70,11 @@ extern "C" #define FSPIM_ERR_CODE_PREFIX FSPIM_ERR_TRANS_FAIL & (FT_ERRCODE_SYS_MODULE_MASK | FT_ERRCODE_SUB_MODULE_MASK) #define FSPIM_NUM_OF_ERR_CODE 8 +typedef enum +{ + FSPIM_DEV_MASTER_MODE = 0 /* only support master mode */ +} FSpimWorkMode; + typedef enum { FSPIM_SLAVE_DEV_0 = 0, @@ -113,10 +124,10 @@ typedef enum typedef enum { - FSPIM_INTR_EVT_RX_DONE = 0, /* 接收完成事件 */ - FSPIM_INTR_EVT_TX_OVERFLOW, /* 发送FIFO上溢事件 */ - FSPIM_INTR_EVT_RX_UNDERFLOW, /* 接收FIFO下溢事件 */ - FSPIM_INTR_EVT_RX_OVERFLOW, /* 接收FIFO上溢事件 */ + FSPIM_INTR_EVT_RX_DONE = 0, /* receive complete event */ + FSPIM_INTR_EVT_TX_OVERFLOW, /* send FIFO overflow event */ + FSPIM_INTR_EVT_RX_UNDERFLOW, /* receive FIFO underflow event */ + FSPIM_INTR_EVT_RX_OVERFLOW, /* receive FIFO overflow event */ FSPIM_INTR_EVT_NUM } FSpimIntrEvtType; @@ -132,6 +143,7 @@ typedef struct uintptr base_addr; /* Device base address */ u32 irq_num; /* Device intrrupt id */ u32 irq_prority; /* Device intrrupt priority */ + FSpimWorkMode work_mode; /* Device work mode */ FSpimSlaveDevice slave_dev_id; /* Slave device id */ u32 max_freq_hz; /* Clock frequency in Hz */ FSpimTransByte n_bytes; /* Bytes in transfer */ @@ -179,10 +191,17 @@ FError FSpimCfgInitialize(FSpim *instance_p, const FSpimConfig *cofig_p); /* 完成I2C驱动实例去使能,清零实例数据 */ void FSpimDeInitialize(FSpim *instance_p); +/* FSPIM临时修改参数操作 */ +FError FSpimSetOption(FSpim *instance_p, u32 option, u32 value); + +/* FSPIM获取某些参数 */ +u32 FSpimGetOption(FSpim *instance_p, u32 option); + /* 先发送后接收数据 (阻塞处理),利用Fifo进行处理 */ FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf, fsize_t len); -#ifdef FSPIM_VERSION_2 /* E2000 */ +#if defined(FSPIM_VERSION_2)/* E2000 */ + /* 启动SPIM DMA数据传输 */ FError FSpimTransferDMA(FSpim *instance_p, boolean tx, boolean rx); diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_g.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_g.c index 5094ff58ea..d61e966e35 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_g.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_g.c @@ -14,13 +14,13 @@ * FilePath: fspim_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:07:55 - * Description:  This files is for + * Description:  This file is for providing spim basic information. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode */ /***************************** Include Files *********************************/ @@ -42,14 +42,15 @@ /************************** Variable Definitions *****************************/ -const FSpimConfig FSPIM_CONFIG_TBL[FSPI_DEVICE_NUM] = +const FSpimConfig FSPIM_CONFIG_TBL[FSPI_NUM] = { [FSPI0_ID] = { .instance_id = FSPI0_ID, /* Id of device*/ - .base_addr = FSPI0_BASE, + .base_addr = FSPI0_BASE_ADDR, .irq_num = FSPI0_IRQ_NUM, .irq_prority = 0, + .work_mode = FSPIM_DEV_MASTER_MODE, .slave_dev_id = FSPIM_SLAVE_DEV_0, .max_freq_hz = 4000000, .n_bytes = 1, @@ -59,22 +60,24 @@ const FSpimConfig FSPIM_CONFIG_TBL[FSPI_DEVICE_NUM] = [FSPI1_ID] = { .instance_id = FSPI1_ID, /* Id of device*/ - .base_addr = FSPI1_BASE, + .base_addr = FSPI1_BASE_ADDR, .irq_num = FSPI1_IRQ_NUM, .irq_prority = 0, + .work_mode = FSPIM_DEV_MASTER_MODE, .slave_dev_id = FSPIM_SLAVE_DEV_0, .max_freq_hz = 4000000, .n_bytes = 1, .en_test = FALSE, .en_dma = FALSE }, -#if defined(CONFIG_TARGET_E2000S) || defined(CONFIG_TARGET_E2000D) || defined(CONFIG_TARGET_E2000Q) +#if defined(CONFIG_TARGET_E2000) [FSPI2_ID] = { .instance_id = FSPI2_ID, /* Id of device*/ .base_addr = FSPI2_BASE, .irq_num = FSPI2_IRQ_NUM, .irq_prority = 0, + .work_mode = FSPIM_DEV_MASTER_MODE, .slave_dev_id = FSPIM_SLAVE_DEV_0, .max_freq_hz = 4000000, .n_bytes = 1, @@ -87,6 +90,7 @@ const FSpimConfig FSPIM_CONFIG_TBL[FSPI_DEVICE_NUM] = .base_addr = FSPI3_BASE, .irq_num = FSPI3_IRQ_NUM, .irq_prority = 0, + .work_mode = FSPIM_DEV_MASTER_MODE, .slave_dev_id = FSPIM_SLAVE_DEV_0, .max_freq_hz = 4000000, .n_bytes = 1, diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.c index c1004bea23..406c3b6ad1 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.c @@ -14,13 +14,14 @@ * FilePath: fspim_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:00 - * Description:  This files is for + * Description:  This file is for providing spim Hardware interaction func. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode + * 1.2 liqiaozhong 2023/1/4 add data get func */ @@ -60,7 +61,7 @@ u32 FSpimGetTxFifoDepth(uintptr base_addr) FSpimSetTxFifoThreshold(base_addr, fifo_depth); if (fifo_depth != FSpimGetTxFifoThreshold(base_addr)) { - FSPIM_INFO("Tx fifo threshold is %d", fifo_depth); + FSPIM_INFO("The Tx fifo threshold is %d", fifo_depth); break; } } @@ -83,7 +84,7 @@ u32 FSpimGetRxFifoDepth(uintptr base_addr) FSpimSetRxFifoThreshold(base_addr, fifo_depth); if (fifo_depth != FSpimGetRxFifoThreshold(base_addr)) { - FSPIM_INFO("Rx fifo threshold is %d", fifo_depth); + FSPIM_INFO("The Rx fifo threshold is %d", fifo_depth); break; } @@ -118,23 +119,48 @@ void FSpimSelSlaveDev(uintptr base_addr, u32 slave_dev_id) * @param {u32} speed, SPI传输速度设置 */ FError FSpimSetSpeed(uintptr base_addr, u32 speed) -{ +{ + FASSERT(speed != 0); u32 clk_div; boolean enabled = FSpimGetEnable(base_addr); if (enabled) + { FSpimSetEnable(base_addr, FALSE); + } - clk_div = FSPI_FREQ / speed; - FSPIM_INFO("set clk div as %d", clk_div); + clk_div = FSPI_CLK_FREQ_HZ / speed; + if (clk_div < FSPIM_BAUD_R_SCKDV_MIN || clk_div > FSPIM_BAUD_R_SCKDV_MAX) + { + FSPIM_ERROR("Clk div is %d => do not support, this parameter should be set as an even from 2 to 65534.", clk_div); + return FSPIM_ERR_NOT_SUPPORT; + } + FSPIM_INFO("Set clk div as %d", clk_div); FSPIM_WRITE_REG32(base_addr, FSPIM_BAUD_R_OFFSET, clk_div); if (enabled) + { FSpimSetEnable(base_addr, TRUE); + } return FSPIM_SUCCESS; } +/** + * @name: FSpimGetSpeed + * @msg: 获取SPI传输速度 + * @return {u32}FSPIM传输频率 + * @param {uintptr} base_addr, SPI控制器基地址 + * @param {u32} speed, SPI传输速度设置 + */ +u32 FSpimGetSpeed(uintptr base_addr) +{ + u32 clk_div; + u32 spim_speed; + + return FSPIM_READ_REG32(base_addr, FSPIM_BAUD_R_OFFSET); +} + /** * @name: FSpimSetTransMode * @msg: 设置SPI传输模式 @@ -149,33 +175,37 @@ void FSpimSetTransMode(uintptr base_addr, u32 trans_mode) boolean enabled = FSpimGetEnable(base_addr); if (enabled) + { FSpimSetEnable(base_addr, FALSE); + } reg_val = FSpimGetCtrlR0(base_addr); reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; /* clear trans mode bits */ switch (trans_mode) { - case FSPIM_TRANS_MODE_RX_TX: - reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); - break; - case FSPIM_TRANS_MODE_TX_ONLY: - reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_TX_ONLY); - break; - case FSPIM_TRANS_MODE_RX_ONLY: - reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); - break; - case FSPIM_TRANS_MODE_READ_EEPROM: - reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RD_EEPROM); - break; - default: - FASSERT(0); - break; + case FSPIM_TRANS_MODE_RX_TX: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + break; + case FSPIM_TRANS_MODE_TX_ONLY: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_TX_ONLY); + break; + case FSPIM_TRANS_MODE_RX_ONLY: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + break; + case FSPIM_TRANS_MODE_READ_EEPROM: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RD_EEPROM); + break; + default: + FASSERT(0); + break; } FSpimSetCtrlR0(base_addr, reg_val); if (enabled) + { FSpimSetEnable(base_addr, TRUE); + } return; } @@ -193,15 +223,41 @@ void FSpimSetCpha(uintptr base_addr, u32 cpha_mode) reg_val &= ~FSPIM_CTRL_R0_SCPHA_MASK; /* clear bits */ if (FSPIM_CPHA_1_EDGE == cpha_mode) + { reg_val |= FSPIM_CTRL_R0_SCPHA(FSPIM_SCPHA_SWITCH_DATA_MID); + } else if (FSPIM_CPHA_2_EDGE == cpha_mode) + { reg_val |= FSPIM_CTRL_R0_SCPHA(FSPIM_SCPHA_SWITCH_DATA_BEG); + } else + { FASSERT(0); + } FSpimSetCtrlR0(base_addr, reg_val); } +/** + * @name: FSpimGetCpha + * @msg: 获取串行时钟相位 + * @return {FSpimCphaType}串行时钟相位 + * @param {uintptr} base_addr, SPI控制器基地址 + */ +FSpimCphaType FSpimGetCpha(uintptr base_addr) +{ + u32 reg_val = FSpimGetCtrlR0(base_addr); + + if (reg_val &= FSPIM_CTRL_R0_SCPHA(FSPIM_SCPHA_SWITCH_DATA_BEG)) + { + return FSPIM_CPHA_2_EDGE; + } + else + { + return FSPIM_CPHA_1_EDGE; + } +} + /** * @name: FSpimSetCpol * @msg: 设置串行时钟极性 @@ -215,15 +271,41 @@ void FSpimSetCpol(uintptr base_addr, u32 cpol_mode) reg_val &= ~FSPIM_CTRL_R0_SCPOL_MASK; /* clear bits */ if (FSPIM_CPOL_LOW == cpol_mode) + { reg_val |= FSPIM_CTRL_R0_SCPOL(FSPIM_SCPOL_INACTIVE_LOW); + } else if (FSPIM_CPOL_HIGH == cpol_mode) + { reg_val |= FSPIM_CTRL_R0_SCPOL(FSPIM_SCPOL_INACTIVE_HIGH); + } else + { FASSERT(0); + } FSpimSetCtrlR0(base_addr, reg_val); } +/** + * @name: FSpimGetCpol + * @msg: 获取串行时钟极性 + * @return {无} + * @param {uintptr} base_addr, SPI控制器基地址 + */ +FSpimCpolType FSpimGetCpol(uintptr base_addr) +{ + u32 reg_val = FSpimGetCtrlR0(base_addr); + + if (reg_val &= FSPIM_CTRL_R0_SCPOL(FSPIM_SCPOL_INACTIVE_HIGH)) + { + return FSPIM_CPOL_HIGH; + } + else + { + return FSPIM_CPOL_LOW; + } +} + /** * @name: FSpimSetSlaveEnable * @msg: 使能/去使能和从设备的连接 @@ -237,20 +319,28 @@ void FSpimSetSlaveEnable(uintptr base_addr, boolean enable) boolean enabled = FSpimGetEnable(base_addr); if (enabled) + { FSpimSetEnable(base_addr, FALSE); + } reg_val = FSpimGetCtrlR0(base_addr); reg_val &= ~FSPIM_CTRL_R0_SLV_OE_MASK; if (enable) + { reg_val |= FSPIM_CTRL_R0_SLV_OE(FSPIM_SLAVE_TX_ENABLE); + } else + { reg_val |= FSPIM_CTRL_R0_SLV_OE(FSPIM_SLAVE_TX_DISALE); + } FSpimSetCtrlR0(base_addr, reg_val); if (enabled) + { FSpimSetEnable(base_addr, TRUE); + } return; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.h b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.h index d66f3bfa30..7519a493c8 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.h @@ -14,14 +14,16 @@ * FilePath: fspim_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:05 - * Description:  This files is for + * Description:  This file is for providing spim Hardware interaction api + * and some predefined variables. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode - * 1.2 zhugengyu 2022-5-13 support spi dma + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode + * 1.2 zhugengyu 2022/5/13 support spi dma + * 1.3 liqiaozhong 2023/1/4 add data get func */ @@ -38,6 +40,7 @@ extern "C" #include "fkernel.h" #include "fio.h" #include "ftypes.h" +#include "fspim.h" /************************** Constant Definitions *****************************/ /** @name Register Map @@ -165,8 +168,8 @@ enum /** @name FSPIM_BAUD_R_OFFSET Register */ #define FSPIM_BAUD_R_SCKDV(x) (GENMASK(15, 0) & ((x) << 0)) /* SCKDV 为 2 ~ 65534 之间的任何偶数值 */ -#define FSPIM_BAUD_R_SCKDV_MIN 2 -#define FSPIM_BAUD_R_SCKDV_MAX 65534 +#define FSPIM_BAUD_R_SCKDV_MIN 2U +#define FSPIM_BAUD_R_SCKDV_MAX 65534U #define FSPIM_BAUD_R_SCKDV_IS_VALID(x) (0 == (x) % 2) /** @name FSPIM_TXFTL_R_OFFSET Register @@ -286,7 +289,6 @@ enum #define FSPIM_TX_DMA_LEVEL 0x10 #define FSPIM_RX_DMA_LEVEL 0xf - /**************************** Type Definitions *******************************/ /************************** Variable Definitions *****************************/ @@ -466,9 +468,13 @@ static inline boolean FSpimGetEnable(uintptr base_addr) static inline void FSpimSetEnable(uintptr base_addr, boolean enable) { if (enable) + { FSPIM_WRITE_REG32(base_addr, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(1)); + } else + { FSPIM_WRITE_REG32(base_addr, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(0)); + } } /** @@ -572,15 +578,24 @@ void FSpimSelSlaveDev(uintptr base_addr, u32 slave_dev_id); /* 设置SPI传输速度 */ FError FSpimSetSpeed(uintptr base_addr, u32 speed); +/* 读取SPI传输速度 */ +u32 FSpimGetSpeed(uintptr base_addr); + /* 设置SPI传输模式 */ void FSpimSetTransMode(uintptr base_addr, u32 trans_mode); /* 设置串行时钟相位 */ void FSpimSetCpha(uintptr base_addr, u32 cpha_mode); -/* 设置串行时钟极性 */ +/* 设置串行时钟相位 */ void FSpimSetCpol(uintptr base_addr, u32 cpol_mode); +/* 读取串行时钟相位 */ +FSpimCphaType FSpimGetCpha(uintptr base_addr); + +/* 读取串行时钟极性 */ +FSpimCpolType FSpimGetCpol(uintptr base_addr); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_intr.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_intr.c index 6d1e85df4d..c1b2945117 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_intr.c @@ -14,13 +14,13 @@ * FilePath: fspim_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:10 - * Description:  This files is for + * Description:  This file is for providing spim interrupt func. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_selftest.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_selftest.c index 1040178d77..c54b8df7dd 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_selftest.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_selftest.c @@ -14,11 +14,13 @@ * FilePath: fspim_selftest.c * Date: 2022-07-21 13:21:43 * LastEditTime: 2022-07-21 13:21:44 - * Description:  This files is for + * Description:  This file is for providing spim self test func. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode */ /***************************** Include Files *********************************/ #include "fio.h" diff --git a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_sinit.c b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_sinit.c index 13b2d17666..fd3c85fc7f 100644 --- a/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_sinit.c @@ -14,13 +14,13 @@ * FilePath: fspim_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:08:24 - * Description:  This files is for + * Description:  This file is for providing spim init basic func. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2021-12-3 init commit - * 1.1 zhugengyu 2022-4-15 support test mode + * 1.0 zhugengyu 2021/12/3 init commit + * 1.1 zhugengyu 2022/4/15 support test mode */ /***************************** Include Files *********************************/ @@ -37,7 +37,7 @@ /************************** Variable Definitions *****************************/ -extern const FSpimConfig FSPIM_CONFIG_TBL[FSPI_DEVICE_NUM]; +extern const FSpimConfig FSPIM_CONFIG_TBL[FSPI_NUM]; /************************** Function Prototypes ******************************/ /** @@ -51,7 +51,7 @@ const FSpimConfig *FSpimLookupConfig(u32 instance_id) const FSpimConfig *ptr = NULL; u32 index; - for (index = 0; index < (u32)FSPI_DEVICE_NUM; index++) + for (index = 0; index < (u32)FSPI_NUM; index++) { if (FSPIM_CONFIG_TBL[index].instance_id == instance_id) { @@ -61,4 +61,4 @@ const FSpimConfig *FSpimLookupConfig(u32 instance_id) } return (const FSpimConfig *)ptr; -} \ No newline at end of file +} diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftacho.c b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftacho.c index 87087e6caa..b7a69c9965 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftacho.c +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftacho.c @@ -14,11 +14,12 @@ * FilePath: ftacho.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-05-20 09:08:52 - * Description:  This files is for + * Description:  This file is for user tacho API implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/05/20 first commit */ /***************************** Include Files *********************************/ @@ -47,7 +48,7 @@ FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p if (instance_p->isready == FT_COMPONENT_IS_READY) { - FTIMER_INFO("device is already initialized.!!!\r\n"); + FTIMER_INFO("Device is already initialized !!!\r\n"); return FTIMER_TACHO_ERR_IS_READ; } @@ -69,7 +70,7 @@ FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTACHO_ERROR("not support work_mode."); + FTACHO_ERROR("Not support work_mode."); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -84,7 +85,7 @@ FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTACHO_ERROR("invalid input 32/64bits."); + FTACHO_ERROR("Invalid input 32/64bits."); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -106,7 +107,7 @@ FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTACHO_ERROR("invalid input edge."); + FTACHO_ERROR("Invalid input edge."); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -142,7 +143,7 @@ FError FTachoGetFanRPM(FTimerTachoCtrl *instance_p, u32 *rpm) if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_TACHO) { - FTIMER_ERROR("device is not already or not work on TACHO_MODE!!!"); + FTIMER_ERROR("Device is not ready or not work on TACHO_MODE!!!"); return FTIMER_TACHO_ERR_NOT_READY; } @@ -176,7 +177,7 @@ FError FTachoGetFanRPM(FTimerTachoCtrl *instance_p, u32 *rpm) { /* calculate rpm */ /* (60(second) * freq * tacho) / (2 * (cmp_l + 1)) cmp_l */ - *rpm = (TIMER_CLK_FREQ_HZ * 60 * raw_dat) / (2 * (cnt_num + 1)); + *rpm = (FTIMER_CLK_FREQ_HZ * 60 * raw_dat) / (2 * (cnt_num + 1)); } return FTIMER_TACHO_SUCCESS; @@ -196,7 +197,7 @@ u32 FTachoGetCaptureCnt(FTimerTachoCtrl *instance_p) if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_CAPTURE) { - FTIMER_ERROR("device is not already or not work on CAPTURE_MODE!!!"); + FTIMER_ERROR("Device is not ready or not work on CAPTURE_MODE!!!"); return FTIMER_TACHO_ERR_NOT_READY; } diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer.c b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer.c index 3b10410b4c..8bfd08c74f 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer.c +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer.c @@ -14,11 +14,12 @@ * FilePath: ftimer.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:09:49 - * Description:  This files is for + * Description:  This file is for user timer API implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/02/18 first commit */ /***************************** Include Files *********************************/ @@ -41,7 +42,7 @@ FError FTimerSoftwareReset(FTimerTachoCtrl *instance_p) if (instance_p->isready != FT_COMPONENT_IS_READY) { - FTIMER_ERROR("device is not already!!!"); + FTIMER_ERROR("Device is not ready!!!"); return FTIMER_TACHO_ERR_NOT_READY; } @@ -149,7 +150,7 @@ static FError TimerSwithBits(FTimerTachoCtrl *instance_p) } else { - FTIMER_ERROR("invalid input"); + FTIMER_ERROR("Invalid input"); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -258,7 +259,7 @@ inline FError FTimerSetStartVal(FTimerTachoCtrl *instance_p, u32 cnt) otherwise the previous cmp val still work */ TimerForceLoad(instance_p); - FTIMER_INFO("set start val 0x%x", FTIMER_STAR_READ(instance_p)); + FTIMER_INFO("Set start val 0x%x", FTIMER_STAR_READ(instance_p)); return ret; } @@ -313,15 +314,15 @@ FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p u32 Ret = FTIMER_TACHO_SUCCESS; if ((FTIMER_ONCE_CMP == config_p->cmp_type) && - (FTIMER_FREE_RUN != config_p->timer_mode)) + (FTIMER_FREE_RUN != config_p->timer_mode)) { - FTIMER_ERROR("time mode shall be free-run when use once timer!!"); + FTIMER_ERROR("Time mode shall be free-run when use once timer!!"); return FTIMER_TACHO_ERR_INVAL_PARM; } if (instance_p->isready == FT_COMPONENT_IS_READY) { - FTIMER_INFO("device is already initialized.!!!\r\n"); + FTIMER_INFO("Device is already initialized.!!!\r\n"); return FTIMER_TACHO_ERR_IS_READ; } @@ -331,7 +332,7 @@ FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTIMER_ERROR("not support"); + FTIMER_ERROR("Not support"); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -345,7 +346,7 @@ FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTIMER_ERROR("invalid input"); + FTIMER_ERROR("Invalid input"); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -359,7 +360,7 @@ FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTIMER_ERROR("invalid input"); + FTIMER_ERROR("Invalid input"); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -373,7 +374,7 @@ FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p } else { - FTIMER_ERROR("invalid input"); + FTIMER_ERROR("Invalid input"); return FTIMER_TACHO_ERR_INVAL_PARM; } @@ -428,32 +429,32 @@ FError FTimeSettingDump(const FTimerTachoCtrl *instance_p) FASSERT(FT_COMPONENT_IS_READY == instance_p->isready); - printf("ctrl: \r\n"); - printf("===%d-bit timer\r\n", is64Bit ? 64 : 32); - printf("===timer enabled: %d\r\n", (CtrlReg & FTIMER_REG_ENABLE) ? 1 : 0); - printf("===timer mode: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_MODE_TIMER) ? 1 : 0); - printf("===once timer: %d\r\n", (CtrlReg & FTIMER_REG_MODE_ONCE) ? 1 : 0); - printf("===restart mode: %d\r\n", (CtrlReg & FTIMER_REG_CNT_RESTART) ? 1 : 0); - printf("===in reset: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_RESET) ? 1 : 0); - printf("===force load: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_FORCE_LOAD) ? 1 : 0); - printf("===clear cnt: %d\r\n", (CtrlReg & FTIMER_REG_CNT_CLR) ? 1 : 0); + FTIMER_DEBUG("ctrl: "); + FTIMER_DEBUG("===%d-bit timer", is64Bit ? 64 : 32); + FTIMER_DEBUG("===timer enabled: %d", (CtrlReg & FTIMER_REG_ENABLE) ? 1 : 0); + FTIMER_DEBUG("===timer mode: %d", (CtrlReg & FTIMER_REG_TACHO_MODE_TIMER) ? 1 : 0); + FTIMER_DEBUG("===once timer: %d", (CtrlReg & FTIMER_REG_MODE_ONCE) ? 1 : 0); + FTIMER_DEBUG("===restart mode: %d", (CtrlReg & FTIMER_REG_CNT_RESTART) ? 1 : 0); + FTIMER_DEBUG("===in reset: %d", (CtrlReg & FTIMER_REG_TACHO_RESET) ? 1 : 0); + FTIMER_DEBUG("===force load: %d", (CtrlReg & FTIMER_REG_TACHO_FORCE_LOAD) ? 1 : 0); + FTIMER_DEBUG("===clear cnt: %d", (CtrlReg & FTIMER_REG_CNT_CLR) ? 1 : 0); - printf("start cnt: 0x%08x\r\n", FTIMER_STAR_READ(instance_p)); + FTIMER_DEBUG("start cnt: 0x%08x", FTIMER_STAR_READ(instance_p)); if (is64Bit) { - printf("cmp low: 0x%08x", FTIMER_CMPL_READ(instance_p)); - printf("high: 0x%08x\r\n", FTIMER_CMPU_READ(instance_p)); - printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p)); - printf("high: 0x%08x\r\n", FTIMER_CNTU_READ(instance_p)); + FTIMER_DEBUG("cmp low: 0x%08x", FTIMER_CMPL_READ(instance_p)); + FTIMER_DEBUG("high: 0x%08x", FTIMER_CMPU_READ(instance_p)); + FTIMER_DEBUG("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p)); + FTIMER_DEBUG("high: 0x%08x", FTIMER_CNTU_READ(instance_p)); } else { - printf("cmp low: 0x%08x\r\n", FTIMER_CMPL_READ(instance_p)); - printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p)); + FTIMER_DEBUG("cmp low: 0x%08x", FTIMER_CMPL_READ(instance_p)); + FTIMER_DEBUG("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p)); } - printf("intr mask: 0x%08x\r\n", FTIMER_INTR_M_READ(instance_p)); - printf("intr status: 0x%08x\r\n", FTIMER_INTR_S_READ(instance_p)); + FTIMER_DEBUG("intr mask: 0x%08x", FTIMER_INTR_M_READ(instance_p)); + FTIMER_DEBUG("intr status: 0x%08x", FTIMER_INTR_S_READ(instance_p)); return FTIMER_TACHO_SUCCESS; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho.h b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho.h index 8f8b4a9edf..7912ca3e76 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho.h +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho.h @@ -14,25 +14,26 @@ * FilePath: ftimer_tacho.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:09:43 - * Description:  This files is for + * Description:  This file is for user ftimer_tacho API definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/02/18 first commit */ -#ifndef BSP_DRIVERS_E2000_TIMER_TACHO_H -#define BSP_DRIVERS_E2000_TIMER_TACHO_H +#ifndef FTIMER_TACHO_H +#define FTIMER_TACHO_H + +#include "ftypes.h" +#include "fdebug.h" +#include "ferror_code.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fdebug.h" -#include "ferror_code.h" - #define FTIMER_TACHO_SUCCESS FT_SUCCESS #define FTIMER_TACHO_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspTimer, 1) #define FTIMER_TACHO_ERR_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspTimer, 2) diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_g.c b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_g.c index 8c4868c3af..6353f21c6e 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_g.c +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_g.c @@ -14,11 +14,12 @@ * FilePath: ftimer_tacho_g.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:09:07 - * Description:  This files is for + * Description:  This file is for timer_tacho static configuration * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/02/18 first commit */ /***************************** Include Files *********************************/ @@ -33,7 +34,7 @@ /************************** Function Prototypes ******************************/ void FTimerGetDefConfig(u32 timer_id, FTimerTachoConfig *config_p) { - FASSERT((timer_id < TIMER_NUM) && (NULL != config_p)); + FASSERT((timer_id < FTIMER_NUM) && (NULL != config_p)); memset(config_p, 0, sizeof(FTimerTachoConfig)); config_p->id = timer_id; @@ -47,7 +48,7 @@ void FTimerGetDefConfig(u32 timer_id, FTimerTachoConfig *config_p) void FTachoGetDefConfig(u32 tacho_id, FTimerTachoConfig *config_p) { - FASSERT((tacho_id < TACHO_NUM) && (NULL != config_p)); + FASSERT((tacho_id < FTACHO_NUM) && (NULL != config_p)); memset(config_p, 0, sizeof(FTimerTachoConfig)); config_p->id = tacho_id; diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_hw.h b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_hw.h index e9bc4d6bd1..d5d937ff8a 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_hw.h @@ -14,26 +14,27 @@ * FilePath: ftimer_tacho_hw.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:09:15 - * Description:  This files is for + * Description:  This file is for timer_tacho register definition * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/02/18 first commit */ -#ifndef BSP_DRIVERS_E2000_TIMER_HW_H -#define BSP_DRIVERS_E2000_TIMER_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FTIMER_TACHO_HW_H +#define FTIMER_TACHO_HW_H #include "fio.h" #include "ftypes.h" #include "fkernel.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* register offset */ #define FTIMER_CTRL_REG_OFFSET (0x0) /*Timer or Tachometer 控制寄存器*/ #define FTACHO_RESULT_REG_OFFSET (0x4) /*一个转速周期内的时钟周期计数结果*/ @@ -134,7 +135,7 @@ extern "C" #define FTIMER_TIMEOUT 3000 /*超时时间*/ -#define FTIMER_BASE_ADDR(instance_p) TIMER_TACHO_BASE_ADDR((instance_p)->config.id) /*获取设备基地址*/ +#define FTIMER_BASE_ADDR(instance_p) FTIMER_TACHO_BASE_ADDR((instance_p)->config.id) /*获取设备基地址*/ /*read and write reg value*/ #define FTIMER_CTRL_READ(instance_p) FTIMER_READ_REG32(FTIMER_BASE_ADDR(instance_p), FTIMER_CTRL_REG_OFFSET) #define FTIMER_CTRL_WRITE(instance_p, regVal) FTIMER_WRITE_REG32(FTIMER_BASE_ADDR(instance_p), FTIMER_CTRL_REG_OFFSET, (regVal)) diff --git a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_intr.c b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_intr.c index 015a0799df..c7318ede81 100644 --- a/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/timer/ftimer_tacho/ftimer_tacho_intr.c @@ -14,18 +14,18 @@ * FilePath: ftimer_tacho_intr.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:09:36 - * Description:  This files is for + * Description:  This file is for timer_tacho interrupt operation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/02/18 first commit */ /***************************** Include Files *********************************/ #include "fassert.h" #include "ftimer_tacho.h" #include "ftimer_tacho_hw.h" -#include "finterrupt.h" /************************** Constant Definitions *****************************/ @@ -99,7 +99,7 @@ void FTimerTachoIntrHandler(s32 vector, void *param) u32 loop; FTimerEventHandler evtHandler; - FTIMER_INFO("intr entered cause: 0x%x.\r\n", intr_status); + FTIMER_INFO("Intr entered cause: 0x%x.\r\n", intr_status); /* check intr status bit by bit */ for (loop = 0; loop < FMAX_TIMER_TACHO_EVENT; loop++) @@ -206,6 +206,6 @@ void FTimerTachoSetIntr(FTimerTachoCtrl *instance_p) { FASSERT(0); } - FTIMER_INFO("mask:0x%x.\r\n", FTIMER_INTR_M_READ(instance_p)); + FTIMER_INFO("Mask:0x%x.\r\n", FTIMER_INTR_M_READ(instance_p)); return; } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/usb/Kconfig b/bsp/phytium/libraries/standalone/drivers/usb/Kconfig index 3ecf7c474c..18d0f459d8 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/usb/Kconfig @@ -5,5 +5,5 @@ config ENABLE_USB_FXHCI depends on USE_USB help Select USB FUSB_HC_XHCI Host driver component - - + + diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb.c index f5e0818757..a7a2fea4b5 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb.c @@ -14,12 +14,12 @@ * FilePath: fusb.c * Date: 2022-02-11 13:33:11 * LastEditTime: 2022-02-18 09:22:06 - * Description:  This files is for implmentation of USB user API + * Description:  This file is for implmentation of USB user API * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/8 init commit + * 1.0 zhugengyu 2022/2/8 init commit */ #include @@ -59,13 +59,17 @@ FError FUsbCfgInitialize(FUsb *instance, const FUsbConfig *input_config) FError ret = FUSB_SUCCESS; if (input_config != &instance->config) + { instance->config = *input_config; + } instance->hc = NULL; /* non usb host attached */ /* create usb hc instance, which will be add as the head of hc list */ if (NULL == FXhciHcInit(instance, instance->config.base_addr)) + { ret = FUSB_ERR_ALLOCATE_FAIL; + } if (FUSB_SUCCESS == ret) { @@ -113,7 +117,9 @@ void FUsbPoll(FUsb *instance) } if (FUsbPollPrepare) + { FUsbPollPrepare(instance); + } FUsbHc *controller = instance->hc; if (controller != NULL) @@ -148,7 +154,9 @@ void FUsbExit(FUsb *instance) } if (FUsbExitPrepare) + { FUsbExitPrepare(instance); + } FUsbHc *controller = instance->hc; if (controller != NULL) @@ -232,7 +240,9 @@ void FUsbMempFreeTag(FUsb *instance, void *ptr) { FASSERT(instance); if (NULL != ptr) + { FMempFreeTag(&instance->memp, ptr); + } return; } @@ -263,7 +273,9 @@ FUsbHc *FUsbAllocateHc(FUsb *instance) void FUsbDetachHc(FUsbHc *controller) { if (controller == NULL) + { return; + } FUsb *instance = controller->usb; FUsbDetachDev(controller, 0); /* tear down root hub tree */ @@ -289,9 +301,9 @@ static FUsbDevInitHandler FUsbFindValidInitFunc(FUsb *instance, const FUsbDevInd { func = &instance->dev_init[loop]; if ((index->category == func->index.category) && - (index->class == func->index.class) && - (index->sub_class == func->index.sub_class) && - (index->protocol == func->index.protocol)) + (index->class == func->index.class) && + (index->sub_class == func->index.sub_class) && + (index->protocol == func->index.protocol)) { handler = func->handler; } @@ -312,7 +324,9 @@ FError FUsbAssignDevInitFunc(FUsb *instance, const FUsbDevIndex *index, FUsbDevI { FASSERT(instance && index && handler); if (FUSB_MAX_DEV_TYPE_NUM == instance->dev_init_num) + { return FUSB_ERR_INVALID_PARA; + } if (NULL != FUsbFindValidInitFunc(instance, index)) { @@ -343,13 +357,13 @@ FUsbDev *FUsbInitDevEntry(FUsbHc *controller, int slot_id) if (NULL == dev) { - FUSB_ERROR("no memory to allocate device structure "); + FUSB_ERROR("No memory to allocate device structure ."); return NULL; } if (controller->devices[slot_id] != NULL) { - FUSB_WARN("warning: device %d reassigned? ", slot_id); + FUSB_WARN("Warning: device %d reassigned? ", slot_id); } controller->devices[slot_id] = dev; @@ -387,7 +401,9 @@ size_t FUsbGetAllDevEntries(FUsbHc *controller, FUsbDev *devs[], size_t max_dev_ /* get at most max_dev_num device entry before exit */ if (num >= max_dev_num) + { break; + } } } @@ -405,43 +421,43 @@ int FUsbDecodeMaxPacketSz0(FUsbSpeed speed, u8 bMaxPacketSize0) { switch (speed) { - case FUSB_LOW_SPEED: - if (bMaxPacketSize0 != 8) - { - FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); - bMaxPacketSize0 = 8; - } - return bMaxPacketSize0; - case FUSB_FULL_SPEED: - switch (bMaxPacketSize0) - { - case 8: - case 16: - case 32: - case 64: + case FUSB_LOW_SPEED: + if (bMaxPacketSize0 != 8) + { + FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); + bMaxPacketSize0 = 8; + } return bMaxPacketSize0; + case FUSB_FULL_SPEED: + switch (bMaxPacketSize0) + { + case 8: + case 16: + case 32: + case 64: + return bMaxPacketSize0; + default: + FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); + return 8; + } + case FUSB_HIGH_SPEED: + if (bMaxPacketSize0 != 64) + { + FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); + bMaxPacketSize0 = 64; + } + return bMaxPacketSize0; + case FUSB_SUPER_SPEED: + /* Intentional fallthrough */ + case FUSB_SUPER_SPEED_PLUS: + if (bMaxPacketSize0 != 9) + { + FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); + bMaxPacketSize0 = 9; + } + return 1 << bMaxPacketSize0; default: - FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); return 8; - } - case FUSB_HIGH_SPEED: - if (bMaxPacketSize0 != 64) - { - FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); - bMaxPacketSize0 = 64; - } - return bMaxPacketSize0; - case FUSB_SUPER_SPEED: - /* Intentional fallthrough */ - case FUSB_SUPER_SPEED_PLUS: - if (bMaxPacketSize0 != 9) - { - FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0); - bMaxPacketSize0 = 9; - } - return 1 << bMaxPacketSize0; - default: - return 8; } } @@ -525,7 +541,9 @@ FUsbTransCode FUsbGetDescriptor(FUsbDev *dev, int rtype, FUsbDescriptorType desc sizeof(dr), &dr, len, data); if (ret == (int)len) + { break; + } fsleep_microsec(10); } @@ -562,7 +580,9 @@ FUsbTransCode FUsbGetStringDescriptor(FUsbDev *dev, int rtype, FUsbDescriptorTyp ret = dev->controller->control(dev, FUSB_IN, sizeof(dr), &dr, len, data); if (ret == (int)len) + { break; + } fsleep_microsec(10); } @@ -624,16 +644,16 @@ int FUsbSpeedtoDefaultMaxPacketSz(FUsbSpeed speed) { switch (speed) { - case FUSB_LOW_SPEED: - return 8; - case FUSB_FULL_SPEED: - case FUSB_HIGH_SPEED: - return 64; - case FUSB_SUPER_SPEED: - /* Intentional fallthrough */ - case FUSB_SUPER_SPEED_PLUS: - default: - return 512; + case FUSB_LOW_SPEED: + return 8; + case FUSB_FULL_SPEED: + case FUSB_HIGH_SPEED: + return 64; + case FUSB_SUPER_SPEED: + /* Intentional fallthrough */ + case FUSB_SUPER_SPEED_PLUS: + default: + return 512; } } @@ -651,47 +671,47 @@ static int FUsbDecodeInterval(FUsbSpeed speed, const FUsbEpType type, const unsi #define LOG2(a) ((sizeof(unsigned) << 3) - __builtin_clz(a) - 1) switch (speed) { - case FUSB_LOW_SPEED: - switch (type) - { - case FUSB_ISOCHRONOUS_EP: - case FUSB_INTERRUPT_EP: - return LOG2(bInterval) + 3; + case FUSB_LOW_SPEED: + switch (type) + { + case FUSB_ISOCHRONOUS_EP: + case FUSB_INTERRUPT_EP: + return LOG2(bInterval) + 3; + default: + return 0; + } + case FUSB_FULL_SPEED: + switch (type) + { + case FUSB_ISOCHRONOUS_EP: + return (bInterval - 1) + 3; + case FUSB_INTERRUPT_EP: + return LOG2(bInterval) + 3; + default: + return 0; + } + case FUSB_HIGH_SPEED: + switch (type) + { + case FUSB_ISOCHRONOUS_EP: + case FUSB_INTERRUPT_EP: + return bInterval - 1; + default: + return LOG2(bInterval); + } + case FUSB_SUPER_SPEED: + /* Intentional fallthrough */ + case FUSB_SUPER_SPEED_PLUS: + switch (type) + { + case FUSB_ISOCHRONOUS_EP: + case FUSB_INTERRUPT_EP: + return bInterval - 1; + default: + return 0; + } default: return 0; - } - case FUSB_FULL_SPEED: - switch (type) - { - case FUSB_ISOCHRONOUS_EP: - return (bInterval - 1) + 3; - case FUSB_INTERRUPT_EP: - return LOG2(bInterval) + 3; - default: - return 0; - } - case FUSB_HIGH_SPEED: - switch (type) - { - case FUSB_ISOCHRONOUS_EP: - case FUSB_INTERRUPT_EP: - return bInterval - 1; - default: - return LOG2(bInterval); - } - case FUSB_SUPER_SPEED: - /* Intentional fallthrough */ - case FUSB_SUPER_SPEED_PLUS: - switch (type) - { - case FUSB_ISOCHRONOUS_EP: - case FUSB_INTERRUPT_EP: - return bInterval - 1; - default: - return 0; - } - default: - return 0; } #undef LOG2 } @@ -717,7 +737,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo FASSERT(instace); if (NULL == dev) { - FUSB_INFO("set_address failed "); + FUSB_INFO("Set address failed."); return FUSB_NO_DEV_ADDR; } @@ -726,22 +746,22 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo if ((NULL == dev->descriptor) || FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_DEVICE, 0, dev->descriptor, sizeof(*dev->descriptor)) != sizeof(*dev->descriptor)) { - FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_DEVICE) failed "); + FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_DEVICE) failed."); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } - FUSB_INFO("* found device (0x%04x:0x%04x, USB %x.%x, MPS0: %d) ", + FUSB_INFO("Found device (0x%04x:0x%04x, USB %x.%x, MPS0: %d) ", dev->descriptor->idVendor, dev->descriptor->idProduct, dev->descriptor->bcdUSB >> 8, dev->descriptor->bcdUSB & 0xff, dev->endpoints[0].maxpacketsize); - FUSB_INFO("device has %d configurations ", + FUSB_INFO("Device has %d configurations.", dev->descriptor->bNumConfigurations); if (dev->descriptor->bNumConfigurations == 0) { /* device isn't usable */ - FUSB_INFO("... no usable configuration! "); + FUSB_INFO("No usable configuration!"); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } @@ -749,7 +769,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo u16 buf[2]; if (FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_CONFIG, 0, buf, sizeof(buf)) != sizeof(buf)) { - FUSB_INFO("first FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed "); + FUSB_INFO("First FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed."); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } @@ -761,7 +781,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo dev->configuration = FUSB_ALLOCATE(instace, buf[1], FUSB_DEFAULT_ALIGN); if (NULL == dev->configuration) { - FUSB_INFO("could not allocate %d bytes for FUSB_DESC_TYPE_CONFIG ", buf[1]); + FUSB_INFO("Could not allocate %d bytes for FUSB_DESC_TYPE_CONFIG.", buf[1]); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } @@ -769,7 +789,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo if (FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_CONFIG, 0, dev->configuration, buf[1]) != buf[1]) { - FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed "); + FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed."); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } @@ -777,7 +797,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo FUsbConfigurationDescriptor *cd = dev->configuration; if (cd->wTotalLength != buf[1]) { - FUSB_INFO("configuration descriptor size changed, aborting "); + FUSB_INFO("Configuration descriptor size changed, aborting."); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } @@ -788,7 +808,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo * else for the time being. If you need it, see the SetInterface and * GetInterface functions in the USB specification and set it yourself. */ - FUSB_INFO("device has %x interfaces ", cd->bNumInterfaces); + FUSB_INFO("Device has %x interfaces.", cd->bNumInterfaces); u8 *end = (void *)dev->configuration + cd->wTotalLength; FUsbInterfaceDescriptor *intf; @@ -799,22 +819,24 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo { if (ptr + 2 > end || !ptr[0] || ptr + ptr[0] > end) { - FUSB_INFO("Couldn't find usable FUSB_DESC_TYPE_INTERFACE "); + FUSB_INFO("Couldn't find usable FUSB_DESC_TYPE_INTERFACE."); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } if (ptr[1] != FUSB_DESC_TYPE_INTERFACE) + { continue; + } intf = (void *)ptr; if (intf->bLength != sizeof(*intf)) { - FUSB_INFO("Skipping broken FUSB_DESC_TYPE_INTERFACE "); + FUSB_INFO("Skipping broken FUSB_DESC_TYPE_INTERFACE."); continue; } - FUSB_INFO("Interface %d: class 0x%x, sub 0x%x. proto 0x%x ", + FUSB_INFO("Interface %d: class 0x%x, sub 0x%x. proto 0x%x.", intf->bInterfaceNumber, intf->bInterfaceClass, intf->bInterfaceSubClass, intf->bInterfaceProtocol); ptr += sizeof(*intf); @@ -827,11 +849,15 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo for (; ptr + 2 <= end && ptr[0] && ptr + ptr[0] <= end; ptr += ptr[0]) { if (ptr[1] == FUSB_DESC_TYPE_INTERFACE || ptr[1] == FUSB_DESC_TYPE_CONFIG || - (size_t)dev->num_endp >= ARRAY_SIZE(dev->endpoints)) + (size_t)dev->num_endp >= ARRAY_SIZE(dev->endpoints)) + { break; + } if (ptr[1] != FUSB_DESC_TYPE_ENDPOINT) + { continue; + } FUsbEndpointDescriptor *desc = (void *)ptr; static const char *transfertypes[4] = @@ -856,47 +882,49 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo } if ((controller->finish_device_config && - controller->finish_device_config(dev)) || - FUsbSetConfiguration(dev) < 0) + controller->finish_device_config(dev)) || + FUsbSetConfiguration(dev) < 0) { - FUSB_INFO("Could not finalize device configuration "); + FUSB_INFO("Could not finalize device configuration. "); FUsbDetachDev(controller, dev->address); return FUSB_NO_DEV_ADDR; } int class = dev->descriptor->bDeviceClass; if (class == 0) + { class = intf->bInterfaceClass; + } switch (class) { - case FUSB_AUDIO_DEVICE: - FUSB_INFO("Audio Class "); - break; - case FUSB_COMM_DEVICE: - FUSB_INFO("Communication Class "); - break; - case FUSB_HID_DEVICE: - FUSB_INFO("HID Class "); - break; - case FUSB_PHYSICAL_DEVICE: - FUSB_INFO("Physical Class"); - break; - case FUSB_IMAGE_DEVICE: - FUSB_INFO("Camera Class "); - break; - case FUSB_PRINTER_DEVICE: - FUSB_INFO("Printer Class"); - break; - case FUSB_MASS_STORAGE_DEVICE: - FUSB_INFO("Mass Storage Class "); - break; - case FUSB_HUB_DEVICE: - FUSB_INFO("Hub Class "); - break; - default: - FUSB_ERROR("Unsupported Class %x ", class); - break; + case FUSB_AUDIO_DEVICE: + FUSB_INFO("Audio Class "); + break; + case FUSB_COMM_DEVICE: + FUSB_INFO("Communication Class "); + break; + case FUSB_HID_DEVICE: + FUSB_INFO("HID Class "); + break; + case FUSB_PHYSICAL_DEVICE: + FUSB_INFO("Physical Class"); + break; + case FUSB_IMAGE_DEVICE: + FUSB_INFO("Camera Class "); + break; + case FUSB_PRINTER_DEVICE: + FUSB_INFO("Printer Class"); + break; + case FUSB_MASS_STORAGE_DEVICE: + FUSB_INFO("Mass Storage Class "); + break; + case FUSB_HUB_DEVICE: + FUSB_INFO("Hub Class "); + break; + default: + FUSB_ERROR("Unsupported Class %x ", class); + break; } index.category = FUSB_STANDARD_INTERFACE; @@ -904,7 +932,7 @@ static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubpo index.sub_class = intf->bInterfaceSubClass; index.protocol = intf->bInterfaceProtocol; - FUSB_INFO("class: 0x%x sub-class: 0x%x, protocol: 0x%x", + FUSB_INFO("Class: 0x%x sub-class: 0x%x, protocol: 0x%x.", index.class, index.sub_class, index.protocol); init_handler = FUsbFindValidInitFunc(instace, &index); @@ -942,7 +970,9 @@ void FUsbDetachDev(FUsbHc *controller, int devno) controller->devices[devno]->destroy(controller->devices[devno]); if (controller->destroy_device) + { controller->destroy_device(controller, devno); + } FUSB_FREE(instace, controller->devices[devno]->descriptor); controller->devices[devno]->descriptor = NULL; @@ -975,7 +1005,9 @@ FUsbDevAddr FUsbAttachDev(FUsbHc *controller, int hubaddress, int port, FUsbSpee : "Unkonwn"); FUsbDevAddr newdev = FUsbSetAddress(controller, speed, port, hubaddress); if (newdev == FUSB_NO_DEV_ADDR) + { return FUSB_NO_DEV_ADDR; + } FUsbDev *newdev_t = controller->devices[newdev]; @@ -995,7 +1027,9 @@ FUsbDevAddr FUsbAttachDev(FUsbHc *controller, int hubaddress, int port, FUsbSpee static void FUsbGenericDestory(FUsbDev *dev) { if (FUsbGenericRemove) + { FUsbGenericRemove(dev); + } return; } @@ -1012,11 +1046,13 @@ void FUsbGenericDevInit(FUsbDev *dev) dev->destroy = FUsbGenericDestory; if (FUsbGenericCreate) + { FUsbGenericCreate(dev); + } if (dev->data == NULL) { - FUSB_INFO("Detaching device not used by payload "); + FUSB_INFO("Detaching device not used by payload."); FUsbDetachDev(dev->controller, dev->address); } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb.h index 7967cb1b49..fde6391d31 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb.h @@ -19,16 +19,11 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_FUSB_H -#define DRIVERS_FUSB_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FUSB_H +#define FUSB_H /***************************** Include Files *********************************/ #include "ftypes.h" @@ -36,6 +31,11 @@ extern "C" #include "fassert.h" #include "fusb_def.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ #define FUSB_SUCCESS FT_SUCCESS #define FUSB_ERR_WAIT_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrUsb, 0x0) diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_debug.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_debug.c index 7870df0f4d..ebb0c4924d 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_debug.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_debug.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fdebug.h" @@ -47,7 +47,9 @@ void FUsbDumpAllDescriptors(FUsbDev *dev) { FError ret = FUSB_SUCCESS; if ((NULL == dev) || (NULL == dev->configuration)) + { return; + } const FUsbDeviceDescriptor *dev_desc = NULL; const FUsbConfigurationDescriptor *config_desc = NULL; @@ -65,27 +67,35 @@ void FUsbDumpAllDescriptors(FUsbDev *dev) ret = FUsbSetupConfigParser(dev, config_desc, config_desc->wTotalLength); FUsbSetupStringParser(dev); if (FUSB_SUCCESS != ret) + { return; + } if (FUsbIsValidStringIndex(dev_desc->iManufacturer)) { ret = FUsbSearchStringDescriptor(instance, dev, dev_desc->iManufacturer); if (FUSB_SUCCESS == ret) + { printf(" Manufacturer: %s\r\n", FUsbGetString(dev)); + } } if (FUsbIsValidStringIndex(dev_desc->iProduct)) { ret = FUsbSearchStringDescriptor(instance, dev, dev_desc->iProduct); if (FUSB_SUCCESS == ret) + { printf(" Product: %s\r\n", FUsbGetString(dev)); + } } if (FUsbIsValidStringIndex(dev_desc->iSerialNumber)) { ret = FUsbSearchStringDescriptor(instance, dev, dev_desc->iSerialNumber); if (FUSB_SUCCESS == ret) + { printf(" Serial No.: %s\r\n", FUsbGetString(dev)); + } } while (NULL != (if_desc = (const FUsbInterfaceDescriptor *)FUsbGetDescriptorFromParser(parser, FUSB_DESC_TYPE_INTERFACE))) @@ -105,7 +115,9 @@ void FUsbDumpAllDescriptors(FUsbDev *dev) { ret = FUsbSearchStringDescriptor(instance, dev, if_desc->iInterface); if (FUSB_SUCCESS == ret) + { printf(" Interface: %s\r\n", FUsbGetString(dev)); + } } } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_def.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_def.h index 5d66390d21..f2c453d89b 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_def.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_def.h @@ -19,21 +19,22 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_FUSB_DEF_H -#define DRIVERS_FUSB_DEF_H +#ifndef FUSB_DEF_H +#define FUSB_DEF_H + +/***************************** Include Files *********************************/ + +#include "ftypes.h" + #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "ftypes.h" - /************************** Constant Definitions *****************************/ typedef enum { diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_dev.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_dev.c index 2d3fdf0dbd..dad3877a3c 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_dev.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_dev.c @@ -19,13 +19,11 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include - #include "fdebug.h" - #include "fusb_private.h" #define FUSB_DEBUG_TAG "FUSB-DEV" @@ -101,43 +99,43 @@ static FError FUsbParserDescriptor(FUsbConfigParser *parser) alt_len = 0; switch (desc_type) { - case FUSB_DESC_TYPE_CONFIG: - if (FUSB_DESC_TYPE_NONE != last_desc_type) - { - FUSB_ERROR("Configuration descriptor must be the first !!!"); - parser->err_pos = cur_pos; - ret = FUSB_ERR_DESC_PARSE_ERR; - goto err_handle; - } - exp_len = sizeof(FUsbConfigurationDescriptor); - break; - case FUSB_DESC_TYPE_INTERFACE: - if (FUSB_DESC_TYPE_NONE == last_desc_type) - { - FUSB_ERROR("Interface descriptor must not be the first !!!"); - parser->err_pos = cur_pos; - ret = FUSB_ERR_DESC_PARSE_ERR; - goto err_handle; - } - exp_len = sizeof(FUsbInterfaceDescriptor); - break; - case FUSB_DESC_TYPE_ENDPOINT: - if ((FUSB_DESC_TYPE_NONE == last_desc_type) || + case FUSB_DESC_TYPE_CONFIG: + if (FUSB_DESC_TYPE_NONE != last_desc_type) + { + FUSB_ERROR("Configuration descriptor must be the first !!!"); + parser->err_pos = cur_pos; + ret = FUSB_ERR_DESC_PARSE_ERR; + goto err_handle; + } + exp_len = sizeof(FUsbConfigurationDescriptor); + break; + case FUSB_DESC_TYPE_INTERFACE: + if (FUSB_DESC_TYPE_NONE == last_desc_type) + { + FUSB_ERROR("Interface descriptor must not be the first !!!"); + parser->err_pos = cur_pos; + ret = FUSB_ERR_DESC_PARSE_ERR; + goto err_handle; + } + exp_len = sizeof(FUsbInterfaceDescriptor); + break; + case FUSB_DESC_TYPE_ENDPOINT: + if ((FUSB_DESC_TYPE_NONE == last_desc_type) || (FUSB_DESC_TYPE_CONFIG == last_desc_type)) - { - FUSB_ERROR("Endpoint descriptor must follow interface descriptor !!!"); - parser->err_pos = cur_pos; - ret = FUSB_ERR_DESC_PARSE_ERR; - goto err_handle; - } - break; - default: - FUSB_DEBUG("Descriptor %d not handled !!!", desc_type); - break; + { + FUSB_ERROR("Endpoint descriptor must follow interface descriptor !!!"); + parser->err_pos = cur_pos; + ret = FUSB_ERR_DESC_PARSE_ERR; + goto err_handle; + } + break; + default: + FUSB_DEBUG("Descriptor %d not handled !!!", desc_type); + break; } if (((exp_len != 0) && (desc_len != exp_len)) && - ((alt_len == 0) || (desc_len != alt_len))) + ((alt_len == 0) || (desc_len != alt_len))) { FUSB_ERROR("Descriptor %d invalid !!!", desc_type); parser->err_pos = cur_pos; @@ -198,8 +196,8 @@ FError FUsbSetupConfigParser(FUsbDev *dev, const void *buf, u32 buf_len) /* input buffer must start with config desc */ config_desc = (FUsbConfigurationDescriptor *)parser->buf; if ((config_desc->bLength != sizeof(FUsbConfigurationDescriptor)) || - (config_desc->bDescriptorType != FUSB_DESC_TYPE_CONFIG) || - (config_desc->wTotalLength > parser->buf_len)) + (config_desc->bDescriptorType != FUSB_DESC_TYPE_CONFIG) || + (config_desc->wTotalLength > parser->buf_len)) { FUSB_ERROR("Invalid configuration descriptor !!!"); return FUSB_ERR_INVALID_DATA; @@ -256,11 +254,15 @@ const FUsbDescriptor *FUsbGetDescriptorFromParser(FUsbConfigParser *parser, FUsb desc_end = FUSB_SKIP_BYTES(parser->next_pos, desc_len); if (desc_end > parser->end_pos) + { break; + } if ((FUSB_DESC_TYPE_ENDPOINT == type) && - (FUSB_DESC_TYPE_INTERFACE == desc_type)) - break; /* there is no chance to find endpoint desc after interface desc */ + (FUSB_DESC_TYPE_INTERFACE == desc_type)) + { + break; /* there is no chance to find endpoint desc after interface desc */ + } if (type == desc_type) { @@ -352,7 +354,9 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) parser->usb_str = FUSB_ALLOCATE(instance, FUSB_USBSTR_MIN_LEN, FUSB_DEFAULT_ALIGN); if (NULL == parser->usb_str) + { return FUSB_ERR_ALLOCATE_FAIL; + } /* get header of string for the full length */ if (FUsbGetStringDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_STRING, id, FUSB_DEFAULT_LANG_ID, @@ -365,8 +369,8 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) /* check if string descriptor header is valid */ total_len = parser->usb_str->len; if ((total_len < FUSB_DESCRIPTOR_HEADER_SIZE) || - ((total_len & 1) != 0) || - (parser->usb_str->type != FUSB_DESC_TYPE_STRING)) + ((total_len & 1) != 0) || + (parser->usb_str->type != FUSB_DESC_TYPE_STRING)) { FUSB_ERROR("Get invalid string descriptor (len: %d) !!!", FUSB_USBSTR_MIN_LEN); return FUSB_ERR_DESC_PARSE_ERR; @@ -374,7 +378,9 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) /* return if no need to get more */ if (total_len <= FUSB_USBSTR_MIN_LEN) + { return FUSB_SUCCESS; + } /* re-malloc usb string desc buffer with full length */ FASSERT(parser->usb_str); @@ -383,7 +389,9 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) parser->usb_str = FUSB_ALLOCATE(instance, total_len, FUSB_DEFAULT_ALIGN); if (NULL == parser->usb_str) + { return FUSB_ERR_ALLOCATE_FAIL; + } /* get the whole string descriptor */ if (FUsbGetStringDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_STRING, id, FUSB_DEFAULT_LANG_ID, @@ -394,8 +402,8 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) } if ((parser->usb_str->len < FUSB_DESCRIPTOR_HEADER_SIZE) || - ((parser->usb_str->len & 1) != 0) || - (parser->usb_str->type != FUSB_DESC_TYPE_STRING)) + ((parser->usb_str->len & 1) != 0) || + (parser->usb_str->type != FUSB_DESC_TYPE_STRING)) { FUSB_ERROR("Get invalid string descriptor (len: %d) !!!", total_len); return FUSB_ERR_DESC_PARSE_ERR; @@ -414,7 +422,7 @@ FError FUsbSearchStringDescriptor(FUsb *instance, FUsbDev *dev, u8 id) { character = usb_str->string[i]; if (character < ' ' /* 0x20 */ - || character > '~') /* 0x7E */ + || character > '~') /* 0x7E */ { character = '_'; } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_g.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_g.c index dd088f21bd..a8f32188f0 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_g.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_g.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.c index 5aa2236124..2b15580396 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fsleep.h" @@ -38,7 +38,9 @@ void FUsbGenericHubDestory(FUsbDev *const dev) FUsbGenericHub *const hub = FUSB_GEN_HUB_GET(dev); FUsb *instace = dev->controller->usb; if (!hub) + { return; + } /* First, detach all devices behind this hub */ int port; @@ -46,7 +48,7 @@ void FUsbGenericHubDestory(FUsbDev *const dev) { if (hub->ports[port] >= 0) { - FUSB_INFO("generic_hub: Detachment at port %d ", port); + FUSB_INFO("Generic hub: Detachment at port %d ", port); FUsbDetachDev(dev->controller, hub->ports[port]); hub->ports[port] = FUSB_NO_DEV_ADDR; } @@ -56,7 +58,9 @@ void FUsbGenericHubDestory(FUsbDev *const dev) if (hub->ops->disable_port) { for (port = 1; port <= hub->num_ports; ++port) + { hub->ops->disable_port(dev, port); + } } FUSB_FREE(instace, hub->ports); // free(hub->ports); @@ -80,7 +84,9 @@ static int FUsbGenericHubDebounce(FUsbDev *const dev, const int port) const int changed = hub->ops->port_status_changed(dev, port); const int connected = hub->ops->port_connected(dev, port); if (changed < 0 || connected < 0) + { return -1; + } if (!changed && connected) { @@ -88,14 +94,16 @@ static int FUsbGenericHubDebounce(FUsbDev *const dev, const int port) } else { - FUSB_INFO("generic_hub: Unstable connection at %d ", + FUSB_INFO("Generic hub: Unstable connection at %d ", port); stable_ms = 0; } total_ms += step_ms; } if (total_ms >= timeout_ms) - FUSB_INFO("generic_hub: Debouncing timed out at %d ", port); + { + FUSB_INFO("Generic hub: Debouncing timed out at %d ", port); + } return 0; /* ignore timeouts, try to always go on */ } @@ -109,9 +117,13 @@ int FUsbGenericHubWaitForPort(FUsbDev *const dev, const int port, { state = port_op(dev, port); if (state < 0) + { return -1; + } else if (!!state == wait_for) + { return timeout_steps; + } fsleep_microsec(step_us); --timeout_steps; } @@ -125,7 +137,9 @@ int FUsbGenericHubResetPort(FUsbDev *const dev, const int port) FUsbGenericHub *const hub = FUSB_GEN_HUB_GET(dev); if (hub->ops->start_port_reset(dev, port) < 0) + { return -1; + } /* wait for 10ms (usb20 spec 11.5.1.5: reset should take 10 to 20ms) */ fsleep_millisec(10); @@ -135,9 +149,13 @@ int FUsbGenericHubResetPort(FUsbDev *const dev, const int port) /* time out after 120 * 100us = 12ms */ dev, port, 0, hub->ops->port_in_reset, 120, 100); if (ret < 0) + { return -1; + } else if (!ret) - FUSB_INFO("generic_hub: Reset timed out at port %d ", port); + { + FUSB_INFO("Generic hub: Reset timed out at port %d ", port); + } return 0; /* ignore timeouts, try to always go on */ } @@ -157,17 +175,21 @@ static int FUsbGenericHubAttachDev(FUsbDev *const dev, const int port) FUsbGenericHub *const hub = FUSB_GEN_HUB_GET(dev); if (FUsbGenericHubDebounce(dev, port) < 0) + { return -1; + } if (hub->ops->reset_port) { if (hub->ops->reset_port(dev, port) < 0) + { return -1; + } if (!hub->ops->port_connected(dev, port)) { FUSB_INFO( - "generic_hub: Port %d disconnected after " + "Generic hub: Port %d disconnected after " "reset. Possibly upgraded, rescan required. ", port); return 0; @@ -178,9 +200,11 @@ static int FUsbGenericHubAttachDev(FUsbDev *const dev, const int port) /* time out after 1,000 * 10us = 10ms */ dev, port, 1, hub->ops->port_enabled, 1000, 10); if (ret < 0) + { return -1; + } else if (!ret) - FUSB_INFO("generic_hub: Port %d still " + FUSB_INFO("Generic hub: Port %d still " "disabled after 10ms ", port); } @@ -188,9 +212,11 @@ static int FUsbGenericHubAttachDev(FUsbDev *const dev, const int port) const FUsbSpeed speed = hub->ops->port_speed(dev, port); if (speed >= 0) { - FUSB_DEBUG("generic_hub: Success at port %d ", port); + FUSB_DEBUG("Generic hub: Success at port %d ", port); if (hub->ops->reset_port) - fsleep_millisec(10); /* Reset recovery time + { + fsleep_millisec(10); + } /* Reset recovery time (usb20 spec 7.1.7.5) */ hub->ports[port] = FUsbAttachDev( dev->controller, dev->address, port, speed); @@ -204,15 +230,17 @@ int FUsbGenericHubScanPort(FUsbDev *const dev, const int port) if (hub->ports[port] >= 0) { - FUSB_INFO("generic_hub: Detachment at port %d ", port); + FUSB_INFO("Generic hub: Detachment at port %d ", port); const int ret = FUsbGenericHubDetachDev(dev, port); if (ret < 0) + { return ret; + } } if (hub->ops->port_connected(dev, port)) { - FUSB_INFO("generic_hub: Attachment at port %d ", port); + FUSB_INFO("Generic hub: Attachment at port %d ", port); return FUsbGenericHubAttachDev(dev, port); } @@ -223,10 +251,12 @@ static void FUsbGenericHubPoll(FUsbDev *const dev) { FUsbGenericHub *const hub = FUSB_GEN_HUB_GET(dev); if (!hub) + { return; + } if (hub->ops->hub_status_changed && - hub->ops->hub_status_changed(dev) != FUSB_CC_SUCCESS) + hub->ops->hub_status_changed(dev) != FUSB_CC_SUCCESS) { return; } @@ -242,9 +272,11 @@ static void FUsbGenericHubPoll(FUsbDev *const dev) } else if (ret == FUSB_CC_SUCCESS) { - FUSB_INFO("generic_hub: Port change at %d ", port); + FUSB_INFO("Generic hub: Port change at %d ", port); if (FUsbGenericHubScanPort(dev, port) < 0) + { return; + } } } } @@ -261,7 +293,7 @@ int FUsbGenericHubInit(FUsbDev *const dev, const int num_ports, dev->data = FUSB_ALLOCATE(instance, sizeof(FUsbGenericHub), FUSB_DEFAULT_ALIGN); if (NULL == dev->data) { - FUSB_ERROR("generic_hub: ERROR: Out of memory "); + FUSB_ERROR("Generic hub: Out of memory "); return -1; } @@ -272,20 +304,24 @@ int FUsbGenericHubInit(FUsbDev *const dev, const int num_ports, hub->ops = ops; if (NULL == hub->ports) { - FUSB_ERROR("generic_hub: ERROR: Out of memory "); + FUSB_ERROR("Generic hub: Out of memory "); FUSB_FREE(instance, dev->data); dev->data = NULL; return -1; } for (port = 1; port <= num_ports; ++port) + { hub->ports[port] = FUSB_NO_DEV_ADDR; + } /* Enable all ports */ if (ops->enable_port) { for (port = 1; port <= num_ports; ++port) + { ops->enable_port(dev, port); + } /* wait once for all ports */ fsleep_millisec(20); diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.h index da3bd6cc2d..ce91d73f0b 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_generic_hub.h @@ -19,19 +19,19 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_FUSB_GENERIC_HUB_H -#define DRIVERS_FUSB_GENERIC_HUB_H +#ifndef FUSB_GENERIC_HUB_H +#define FUSB_GENERIC_HUB_H + +#include "fusb_private.h" #ifdef __cplusplus extern "C" { #endif -#include "fusb_private.h" - typedef struct { /* negative results denote an error */ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.c index a2df9e6e13..89d1867bfa 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.c @@ -14,11 +14,12 @@ * FilePath: fusb_hid.c * Date: 2022-09-28 18:26:42 * LastEditTime: 2022-09-29 14:50:09 - * Description:  This files is for + * Description:  This files is for usb hid class implmentation * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/9/28 init commit */ #include @@ -93,11 +94,17 @@ static void FUsbHidDestory(FUsbDev *dev) for (i = 0; i <= dev->num_endp; i++) { if (dev->endpoints[i].endpoint == 0) + { continue; + } if (dev->endpoints[i].type != FUSB_INTERRUPT_EP) + { continue; + } if (dev->endpoints[i].direction != FUSB_IN) + { continue; + } break; } dev->controller->destroy_intr_queue( @@ -278,7 +285,9 @@ static void FUsbHidKeyboardQueue(int ch) { /* ignore key presses if buffer full */ if (keycount < KEYBOARD_BUFFER_SIZE) + { keybuffer[keycount++] = ch; + } } /* handle hid received data */ @@ -292,22 +301,34 @@ static void FUsbHidProcessKeyboardEvent(FUsbHid *const inst, modifiers = 0; if (current->modifiers & 0x01) /* Left-Ctrl */ + { modifiers |= KB_MOD_CTRL; + } if (current->modifiers & 0x02) /* Left-Shift */ + { modifiers |= KB_MOD_SHIFT; + } if (current->modifiers & 0x04) /* Left-Alt */ + { modifiers |= KB_MOD_ALT; + } if (current->modifiers & 0x08) /* Left-GUI */ { } if (current->modifiers & 0x10) /* Right-Ctrl */ + { modifiers |= KB_MOD_CTRL; + } if (current->modifiers & 0x20) /* Right-Shift */ + { modifiers |= KB_MOD_SHIFT; + } if (current->modifiers & 0x40) /* Right-AltGr */ + { modifiers |= KB_MOD_ALT; + } if (current->modifiers & 0x80) /* Right-GUI */ { @@ -321,7 +342,7 @@ static void FUsbHidProcessKeyboardEvent(FUsbHid *const inst, /* Did the event change at all? */ if (inst->lastkeypress && - !memcmp(current, previous, sizeof(*current))) + !memcmp(current, previous, sizeof(*current))) { /* No. Then it's a key repeat event. */ if (inst->repeat_delay) @@ -345,7 +366,9 @@ static void FUsbHidProcessKeyboardEvent(FUsbHid *const inst, int skip = 0; /* No more keys? skip */ if (current->keys[i] == 0) + { return; + } for (j = 0; j < 6; j++) { @@ -357,7 +380,9 @@ static void FUsbHidProcessKeyboardEvent(FUsbHid *const inst, } if (skip) + { continue; + } /* Mask off KB_MOD_CTRL */ keypress = map->map[modifiers & 0x03][current->keys[i]]; @@ -366,11 +391,11 @@ static void FUsbHidProcessKeyboardEvent(FUsbHid *const inst, { switch (keypress) { - case 'a' ... 'z': - keypress &= 0x1f; - break; - default: - continue; + case 'a' ... 'z': + keypress &= 0x1f; + break; + default: + continue; } } @@ -441,7 +466,9 @@ static int FUsbHidSetLayout(const char *country) { if (strncmp(keyboard_layouts[i].country, country, strlen(keyboard_layouts[i].country))) + { continue; + } /* Found, changing keyboard layout */ map = &keyboard_layouts[i]; @@ -471,62 +498,68 @@ void FUsbHidInit(FUsbDev *dev) boot_protos[interface->bInterfaceProtocol]); switch (interface->bInterfaceProtocol) { - case FUSB_HID_BOOT_PROTOCOL_KEYBOARD: - dev->data = FUSB_ALLOCATE(instance, sizeof(FUsbHid), FUSB_DEFAULT_ALIGN); - FUSB_DEBUG(" configuring...\n"); - FUsbHidSetProtocol(dev, interface, FUSB_HID_PROTOCOL_BOOT); - FUsbHidSetIdle(dev, interface, KEYBOARD_REPEAT_MS); - FUSB_DEBUG(" activating...\n"); + case FUSB_HID_BOOT_PROTOCOL_KEYBOARD: + dev->data = FUSB_ALLOCATE(instance, sizeof(FUsbHid), FUSB_DEFAULT_ALIGN); + FUSB_DEBUG(" configuring...\n"); + FUsbHidSetProtocol(dev, interface, FUSB_HID_PROTOCOL_BOOT); + FUsbHidSetIdle(dev, interface, KEYBOARD_REPEAT_MS); + FUSB_DEBUG(" activating...\n"); - FUsbHidDescriptor *desc = FUSB_ALLOCATE(instance, sizeof(FUsbHidDescriptor), FUSB_DEFAULT_ALIGN); - if (!desc || FUsbGetDescriptor(dev, FUsbGenerateReqType( - FUSB_REQ_DEVICE_TO_HOST, FUSB_REQ_TYPE_STANDARD, FUSB_REQ_RECP_IF), - 0x21, 0, desc, sizeof(*desc)) != sizeof(*desc)) - { - FUSB_DEBUG("FUsbGetDescriptor(HID) failed\n"); - FUsbDetachDev(dev->controller, dev->address); - return; - } - FUSB_HID_INST(dev)->descriptor = desc; - countrycode = desc->bCountryCode; - /* 35 countries defined: */ - if (countrycode >= ARRAY_SIZE(countries)) - countrycode = 0; - printf(" Keyboard has %s layout (country code %02x)\n", - countries[countrycode][0], countrycode); + FUsbHidDescriptor *desc = FUSB_ALLOCATE(instance, sizeof(FUsbHidDescriptor), FUSB_DEFAULT_ALIGN); + if (!desc || FUsbGetDescriptor(dev, FUsbGenerateReqType( + FUSB_REQ_DEVICE_TO_HOST, FUSB_REQ_TYPE_STANDARD, FUSB_REQ_RECP_IF), + 0x21, 0, desc, sizeof(*desc)) != sizeof(*desc)) + { + FUSB_DEBUG("FUsbGetDescriptor(HID) failed\n"); + FUsbDetachDev(dev->controller, dev->address); + return; + } + FUSB_HID_INST(dev)->descriptor = desc; + countrycode = desc->bCountryCode; + /* 35 countries defined: */ + if (countrycode >= ARRAY_SIZE(countries)) + { + countrycode = 0; + } + FUSB_INFO(" Keyboard has %s layout (country code %02x)\n", + countries[countrycode][0], countrycode); - /* Set keyboard layout accordingly */ - FUsbHidSetLayout(countries[countrycode][1]); + /* Set keyboard layout accordingly */ + FUsbHidSetLayout(countries[countrycode][1]); - // only add here, because we only support boot-keyboard HID devices - dev->destroy = FUsbHidDestory; - dev->poll = FUsbHidPoll; - int i; - for (i = 1; i < dev->num_endp; i++) - { - if (dev->endpoints[i].type != FUSB_INTERRUPT_EP) - continue; - if (dev->endpoints[i].direction != FUSB_IN) - continue; + // only add here, because we only support boot-keyboard HID devices + dev->destroy = FUsbHidDestory; + dev->poll = FUsbHidPoll; + int i; + for (i = 1; i < dev->num_endp; i++) + { + if (dev->endpoints[i].type != FUSB_INTERRUPT_EP) + { + continue; + } + if (dev->endpoints[i].direction != FUSB_IN) + { + continue; + } + break; + } + + if (i >= dev->num_endp) + { + FUSB_DEBUG("Could not find HID endpoint\n"); + FUsbDetachDev(dev->controller, dev->address); + return; + } + + FUSB_DEBUG(" found endpoint %x for interrupt-in\n", i); + /* 20 buffers of 8 bytes, for every 10 msecs */ + FUSB_HID_INST(dev)->queue = dev->controller->create_intr_queue(&dev->endpoints[i], 8, 20, 10); + keycount = 0; + FUSB_DEBUG(" configuration done.\n"); + break; + case FUSB_HID_BOOT_PROTOCOL_MOUSE: + FUSB_DEBUG("NOTICE: USB mice are not supported.\n"); break; - } - - if (i >= dev->num_endp) - { - FUSB_DEBUG("Could not find HID endpoint\n"); - FUsbDetachDev(dev->controller, dev->address); - return; - } - - FUSB_DEBUG(" found endpoint %x for interrupt-in\n", i); - /* 20 buffers of 8 bytes, for every 10 msecs */ - FUSB_HID_INST(dev)->queue = dev->controller->create_intr_queue(&dev->endpoints[i], 8, 20, 10); - keycount = 0; - FUSB_DEBUG(" configuration done.\n"); - break; - case FUSB_HID_BOOT_PROTOCOL_MOUSE: - FUSB_DEBUG("NOTICE: USB mice are not supported.\n"); - break; } } } @@ -544,11 +577,11 @@ int FUsbHidCheckInput(FUsbDev *dev, int times) { ret = keybuffer[0]; memmove(keybuffer, keybuffer + 1, --keycount); - printf("%c", ret); + FUSB_INFO("%c", ret); } fsleep_millisec(10); } - printf("\r\n"); + FUSB_INFO("\r\n"); } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.h index e4bc50e363..da43bbeefd 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hid.h @@ -19,21 +19,21 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/9/28 init commit + * 1.0 zhugengyu 2022/9/28 init commit */ -#ifndef DRIVERS_USB_HID_H -#define DRIVERS_USB_HID_H +#ifndef FUSB_HID_H +#define FUSB_HID_H + +/***************************** Include Files *********************************/ + +#include "fusb.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "fusb.h" - /************************** Constant Definitions *****************************/ /*---------------------------------------------------------------------- * diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.c index a18cd4e09f..bf2bc3cc2c 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.c @@ -20,7 +20,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fkernel.h" @@ -84,8 +84,10 @@ static FUsbEndpoint *FUsbHubIntrEp(FUsbDev *const dev) for (i = 0; i < dev->num_endp; ++i) { if (dev->endpoints[i].type == FUSB_INTERRUPT_EP && - dev->endpoints[i].direction == FUSB_IN) + dev->endpoints[i].direction == FUSB_IN) + { return &dev->endpoints[i]; + } } return NULL; @@ -151,7 +153,9 @@ static FUsbTransCode FUsbHubPortInReset(FUsbDev *const dev, const int port) FUsbTransCode ret = FUsbGetStatus(dev, port, DR_PORT, sizeof(buf), buf); if (ret >= FUSB_CC_ZERO_BYTES) + { ret = buf[FUSB_HUB_PORT_STATUS] & FUSB_HUB_STATUS_PORT_RESET; + } return ret; } @@ -170,7 +174,9 @@ static FUsbTransCode FUsbHubPortEnabled(FUsbDev *const dev, const int port) FUsbTransCode ret = FUsbGetStatus(dev, port, DR_PORT, sizeof(buf), buf); if (ret >= FUSB_CC_ZERO_BYTES) + { ret = buf[FUSB_HUB_PORT_STATUS] & FUSB_HUB_STATUS_PORT_ENABLE; + } return ret; } @@ -193,7 +199,9 @@ static FUsbSpeed FUsbHubPortSpeed(FUsbDev *const dev, const int port) { /* SuperSpeed hubs can only have SuperSpeed devices. */ if (FUsbIsSuperSpeed(dev->speed)) + { return dev->speed; + } /*[bit] 10 9 (USB 2.0 port status word) * 0 0 full speed @@ -203,7 +211,9 @@ static FUsbSpeed FUsbHubPortSpeed(FUsbDev *const dev, const int port) */ speed = (buf[FUSB_HUB_PORT_STATUS] >> 9) & 0x3; if (speed != 0x3) /* high-speed device */ + { return speed; + } } return FUSB_UNKNOWN_SPEED; @@ -290,14 +300,18 @@ static void FUsbHubPortInit(FUsbDev *const dev, const int port) FUsbTransCode ret = FUsbGetStatus(dev, port, DR_PORT, sizeof(buf), buf); if (ret < FUSB_CC_ZERO_BYTES) + { return; + } if (buf[FUSB_HUB_PORT_CHANGE] & FUSB_HUB_STATUS_PORT_CONNECTION) + { FUsbClearFeature(dev, port, FUSB_HUB_SEL_C_PORT_CONNECTION, DR_PORT); + } if (buf[FUSB_HUB_PORT_STATUS] & FUSB_HUB_STATUS_PORT_CONNECTION) { - FUSB_INFO("usbhub: Port coldplug at %d ", port); + FUSB_INFO("Usb hub: Port coldplug at %d ", port); FUsbGenericHubScanPort(dev, port); } @@ -337,7 +351,9 @@ static FUsbTransCode FUsbHubHandlePortChange(FUsbDev *const dev, const int port) ret = FUsbGetStatus(dev, port, DR_PORT, sizeof(buf), buf); if (ret < FUSB_CC_ZERO_BYTES) + { return ret; + } /* * Second word holds the change bits. The interrupt transfer shows @@ -355,7 +371,9 @@ static FUsbTransCode FUsbHubHandlePortChange(FUsbDev *const dev, const int port) } if (buf[FUSB_HUB_PORT_CHANGE] & ~checked_bits) + { FUSB_DEBUG("Spurious change bit at port %d ", port); + } /* Now, handle connection changes. */ if (buf[FUSB_HUB_PORT_CHANGE] & FUSB_HUB_STATUS_PORT_CONNECTION) @@ -387,7 +405,9 @@ static void FUsbHubPoll(FUsbDev *const dev) while (NULL != (ibuf = dev->controller->poll_intr_queue(FUSB_GEN_HUB_GET(dev)->data))) { for (i = 0; (size_t)i < port_bytes; ++i) + { buf[i] |= ibuf[i]; + } } for (port = 1; port <= FUSB_GEN_HUB_GET(dev)->num_ports; ++port) @@ -396,7 +416,9 @@ static void FUsbHubPoll(FUsbDev *const dev) if (buf[port / 8] & (1 << (port % 8))) { if (FUsbHubHandlePortChange(dev, port) < 0) + { return; + } } } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.h index 5e6235a11f..62750491d9 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_hub.h @@ -19,21 +19,21 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_USB_HUB_H -#define DRIVERS_USB_HUB_H +#ifndef FUSB_HUB_H +#define FUSB_HUB_H + +/***************************** Include Files *********************************/ + +#include "fusb.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "fusb.h" - /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.c index 0e6a8a64ef..f48d945eb5 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include @@ -116,7 +116,9 @@ static void FUsbMscRemoveDisk(FUsbDev *dev) FASSERT(dev); if (MSC_INST(dev)->usbdisk_created && FUsbDiskRemove) + { FUsbDiskRemove(dev); + } return; } @@ -222,12 +224,14 @@ static int FUsbMscResetTransport(FUsbDev *dev) dr.wLength = 0; if (MSC_INST(dev)->quirks & FUSB_MSC_QUIRK_NO_RESET) + { return MSC_COMMAND_FAIL; + } /* if any of these fails, detach device, as we are lost */ if (dev->controller->control(dev, FUSB_OUT, sizeof(dr), &dr, 0, 0) < 0 || - FUsbClearStall(MSC_INST(dev)->bulk_in) || - FUsbClearStall(MSC_INST(dev)->bulk_out)) + FUsbClearStall(MSC_INST(dev)->bulk_in) || + FUsbClearStall(MSC_INST(dev)->bulk_out)) { FUSB_INFO("Detaching unresponsive device. "); FUsbDetachDev(dev->controller, dev->address); @@ -253,8 +257,8 @@ static void FUsbMscInitLuns(FUsbDev *dev) /* send class-spefic request Get Max Lun */ if ((MSC_INST(dev)->quirks & FUSB_MSC_QUIRK_NO_LUNS) || - (dev->controller->control(dev, FUSB_IN, sizeof(dr), &dr, - sizeof(msc->num_luns), &msc->num_luns) < FUSB_CC_ZERO_BYTES)) + (dev->controller->control(dev, FUSB_IN, sizeof(dr), &dr, + sizeof(msc->num_luns), &msc->num_luns) < FUSB_CC_ZERO_BYTES)) { msc->num_luns = 0; /* assume only 1 lun if req fails */ } @@ -298,18 +302,22 @@ static int FUsbMscGetCsw(FUsbEndpoint *ep, FUsbMscCsw *csw) /* Some broken sticks send a zero-length packet at the end of their data transfer which would show up here. Skip it to get the actual CSW. */ if (ret == 0) + { ret = ctrlr->bulk(ep, sizeof(FUsbMscCsw), (u8 *)csw, 1); + } if (ret < 0) { FUsbClearStall(ep); ret = ctrlr->bulk(ep, sizeof(FUsbMscCsw), (u8 *)csw, 1); if (ret < 0) + { return FUsbMscResetTransport(ep->dev); + } } if (ret != sizeof(FUsbMscCsw) || csw->dCSWTag != tag || - csw->dCSWSignature != csw_signature) + csw->dCSWSignature != csw_signature) { FUSB_INFO("MSC: received malformed CSW "); return FUsbMscResetTransport(ep->dev); @@ -343,12 +351,16 @@ static int FUsbMscExecCmd(FUsbDev *dev, FUsbMassStorageDirection dir, const u8 * if (dir == FUSB_DIR_DATA_IN) { if (dev->controller->bulk(MSC_INST(dev)->bulk_in, buflen, buf, 0) < 0) + { FUsbClearStall(MSC_INST(dev)->bulk_in); + } } else { if (dev->controller->bulk(MSC_INST(dev)->bulk_out, buflen, buf, 0) < 0) + { FUsbClearStall(MSC_INST(dev)->bulk_out); + } } } @@ -372,21 +384,29 @@ static int FUsbMscExecCmd(FUsbDev *dev, FUsbMassStorageDirection dir, const u8 * { if ((csw.dCSWDataResidue == 0) || residue_ok) /* no error, exit */ + { return MSC_COMMAND_OK; + } else /* missed some bytes */ + { return MSC_COMMAND_FAIL; + } } else { if (cb[0] == 0x03) /* requesting sense failed, that's bad */ + { return MSC_COMMAND_FAIL; + } else if (cb[0] == 0) /* If command was TEST UNIT READY determine if the * device is of removable type indicating no media * found. */ + { return FUsbMscRequestNoMedia(dev); + } /* error "check condition" or reserved error */ ret = FUsbMscRequestSense(dev); /* return fail or the status of FUsbMscRequestSense if it's worse */ @@ -510,7 +530,9 @@ static int FUsbMscRwBlks(FUsbDev *dev, int start, int n, FUsbMassStorageDirectio if (FUsbMscRwChunk(dev, start + (chunk * chunk_size), chunk_size, dir, buf + (chunk * MAX_CHUNK_BYTES)) != MSC_COMMAND_OK) + { return 1; + } } /* Read any remaining partial chunk at the end. */ @@ -519,7 +541,9 @@ static int FUsbMscRwBlks(FUsbDev *dev, int start, int n, FUsbMassStorageDirectio if (FUsbMscRwChunk(dev, start + (chunk * chunk_size), n % chunk_size, dir, buf + (chunk * MAX_CHUNK_BYTES)) != MSC_COMMAND_OK) + { return 1; + } } return 0; @@ -553,15 +577,21 @@ static int FUsbMscRequestNoMedia(FUsbDev *dev) sizeof(cb), buf, sizeof(buf), 1); if (ret) + { return ret; + } /* Check if sense key is set to NOT READY. */ if ((buf[2] & 0xf) != 2) + { return MSC_COMMAND_FAIL; + } /* Check if additional sense code is 0x3a. */ if (buf[12] != 0x3a) + { return MSC_COMMAND_FAIL; + } /* No media is present. Return MSC_COMMAND_OK while marking the disk * not ready. */ @@ -604,19 +634,19 @@ static int FUsbMscReadCapcity(FUsbDev *dev) switch (ret = FUsbMscExecCmd(dev, FUSB_DIR_DATA_IN, (u8 *)&cb, sizeof(cb), (u8 *)buf, 8, 0)) { - case MSC_COMMAND_OK: - break; - case MSC_COMMAND_FAIL: - continue; - default: /* if it's worse return */ - return ret; + case MSC_COMMAND_OK: + break; + case MSC_COMMAND_FAIL: + continue; + default: /* if it's worse return */ + return ret; } break; } if (count >= 20) { /* still not successful, assume 2tb in 512byte sectors, which is just the same garbage as any other number, but probably more usable. */ - FUSB_WARN(" assuming 2 TB with 512-byte sectors as READ CAPACITY didn't answer. "); + FUSB_WARN("Assuming 2 TB with 512-byte sectors as read capacity didn't answer. "); MSC_INST(dev)->numblocks = 0xffffffff; MSC_INST(dev)->blocksize = 512; } @@ -655,15 +685,15 @@ static int FUsbMscWaitReady(FUsbDev *dev) { switch (FUsbMscCheckIfReady(dev)) { - case MSC_COMMAND_OK: - break; - case MSC_COMMAND_FAIL: - fsleep_millisec(100); - FUSB_INFO("."); - continue; - default: - /* Device detached, return immediately */ - return FUSB_MSC_DETACHED; + case MSC_COMMAND_OK: + break; + case MSC_COMMAND_FAIL: + fsleep_millisec(100); + FUSB_INFO("."); + continue; + default: + /* Device detached, return immediately */ + return FUSB_MSC_DETACHED; } break; } @@ -671,7 +701,7 @@ static int FUsbMscWaitReady(FUsbDev *dev) if (FUsbMscTimeout(start_tick, timeout_tick)) { - FUSB_INFO("timeout. Device not ready. "); + FUSB_INFO("Timeout. Device not ready. "); MSC_INST(dev)->ready = FUSB_MSC_NOT_READY; } @@ -679,28 +709,32 @@ static int FUsbMscWaitReady(FUsbDev *dev) * ready. This can happen when empty card readers are present. * Polling will pick it back up if readiness changes. */ if (!MSC_INST(dev)->ready) + { return MSC_INST(dev)->ready; + } for (i = 0; i < 30; i++) { FUSB_INFO("."); switch (FUsbMscSpinUp(dev)) { - case MSC_COMMAND_OK: - FUSB_INFO(" OK."); - break; - case MSC_COMMAND_FAIL: - fsleep_millisec(100); - continue; - default: - /* Device detached, return immediately */ - return FUSB_MSC_DETACHED; + case MSC_COMMAND_OK: + FUSB_INFO(" OK."); + break; + case MSC_COMMAND_FAIL: + fsleep_millisec(100); + continue; + default: + /* Device detached, return immediately */ + return FUSB_MSC_DETACHED; } break; } if (FUsbMscReadCapcity(dev) == MSC_COMMAND_DETACHED) + { return FUSB_MSC_DETACHED; + } return MSC_INST(dev)->ready; } @@ -739,8 +773,8 @@ void FUsbMassStorageInit(FUsbDev *dev) } if ((interface->bInterfaceSubClass != FUSB_MSC_SUBCLASS_ATAPI_8020) && /* ATAPI 8020 */ - (interface->bInterfaceSubClass != FUSB_MSC_SUBCLASS_ATAPI_8070) && /* ATAPI 8070 */ - (interface->bInterfaceSubClass != FUSB_MSC_SUBCLASS_SCSI)) + (interface->bInterfaceSubClass != FUSB_MSC_SUBCLASS_ATAPI_8070) && /* ATAPI 8070 */ + (interface->bInterfaceSubClass != FUSB_MSC_SUBCLASS_SCSI)) { /* SCSI */ /* Other protocols, such as ATAPI don't seem to be very popular. looks like ATAPI would be really easy to add, if necessary. */ @@ -784,19 +818,27 @@ static void FUsbMassStorageForceInit(FUsbDev *dev, u32 quirks) for (i = 1; i <= dev->num_endp; i++) { if (dev->endpoints[i].endpoint == 0) + { continue; + } if (dev->endpoints[i].type != FUSB_BULK_EP) + { continue; + } if ((dev->endpoints[i].direction == FUSB_IN) && (MSC_INST(dev)->bulk_in == 0)) + { MSC_INST(dev)->bulk_in = &dev->endpoints[i]; + } if ((dev->endpoints[i].direction == FUSB_OUT) && (MSC_INST(dev)->bulk_out == 0)) + { MSC_INST(dev)->bulk_out = &dev->endpoints[i]; + } } /* check if non bulk-in ep */ if (MSC_INST(dev)->bulk_in == NULL) { - FUSB_ERROR("couldn't find bulk-in endpoint. "); + FUSB_ERROR("Couldn't find bulk-in endpoint."); FUsbDetachDev(dev->controller, dev->address); return; } @@ -804,12 +846,12 @@ static void FUsbMassStorageForceInit(FUsbDev *dev, u32 quirks) /* check if non bulk-out ep */ if (MSC_INST(dev)->bulk_out == NULL) { - FUSB_ERROR("couldn't find bulk-out endpoint. "); + FUSB_ERROR("Couldn't find bulk-out endpoint."); FUsbDetachDev(dev->controller, dev->address); return; } - FUSB_INFO("using endpoint %x as in, %x as out ", + FUSB_INFO("Using endpoint %x as in, %x as out.", MSC_INST(dev)->bulk_in->endpoint, MSC_INST(dev)->bulk_out->endpoint); @@ -817,11 +859,13 @@ static void FUsbMassStorageForceInit(FUsbDev *dev, u32 quirks) fsleep_microsec(50); FUsbMscInitLuns(dev); - FUSB_INFO(" has %d luns ", MSC_INST(dev)->num_luns); + FUSB_INFO("Has %d luns.", MSC_INST(dev)->num_luns); /* Test if msc is ready (nothing to do if it isn't). */ if (FUsbMscWaitReady(dev) != FUSB_MSC_READY) + { return; + } /* Create the disk. */ FUsbMscCreateDisk(dev); @@ -835,7 +879,9 @@ static void FUsbMscPoll(FUsbDev *dev) int prev_ready = msc->ready; if (FUsbMscWaitReady(dev) == FUSB_MSC_DETACHED) + { return; + } if (!prev_ready && msc->ready) { diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.h index bc0a1989b9..0e9d7c2eef 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_msc.h @@ -19,21 +19,21 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_USB_MSC_H -#define DRIVERS_USB_MSC_H +#ifndef FUSB_MSC_H +#define FUSB_MSC_H + +/***************************** Include Files *********************************/ + +#include "fusb.h" #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ - -#include "fusb.h" - /************************** Constant Definitions *****************************/ /* Possible values for quirks field. */ enum diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_private.h b/bsp/phytium/libraries/standalone/drivers/usb/fusb_private.h index b1db521507..859db19a09 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_private.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_private.h @@ -19,10 +19,11 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#pragma once +#ifndef FUSB_PRIVATE_H +#define FUSB_PRIVATE_H /***************************** Include Files *********************************/ #ifdef __aarch64__ @@ -36,6 +37,11 @@ #include "fassert.h" #include "fusb.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -101,4 +107,10 @@ void FUsbDumpConfigDescriptor(const FUsbConfigurationDescriptor *descriptor); void FUsbDumpInterfaceDescriptor(const FUsbInterfaceDescriptor *descriptor); /* 打印端点描述符信息 */ -void FUsbDumpEndpointDescriptor(const FUsbEndpointDescriptor *descriptor); \ No newline at end of file +void FUsbDumpEndpointDescriptor(const FUsbEndpointDescriptor *descriptor); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fusb_sinit.c b/bsp/phytium/libraries/standalone/drivers/usb/fusb_sinit.c index cf5af243e1..fe4f5e6283 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fusb_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fusb_sinit.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/8 init version + * 1.0 zhugengyu 2022/2/8 init version */ /***************************** Include Files *********************************/ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.c index 17b5538d47..ce11238173 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include @@ -73,12 +73,18 @@ void *FXhciAlign(FXhci *const xhci, const size_t min_align, const size_t size) FUsb *instance = xhci->usb; if (!(size & (size - 1))) - align = size; /* It's a power of 2 */ + { + align = size; /* It's a power of 2 */ + } else + { align = 1 << ((sizeof(unsigned) << 3) - __builtin_clz(size)); + } if (align < min_align) + { align = min_align; + } return FUSB_ALLOCATE(instance, size, align); } @@ -91,12 +97,18 @@ void *FXhciAlignTag(FXhci *const xhci, const size_t min_align, const size_t size FUsb *instance = xhci->usb; if (!(size & (size - 1))) - align = size; /* It's a power of 2 */ + { + align = size; /* It's a power of 2 */ + } else + { align = 1 << ((sizeof(unsigned) << 3) - __builtin_clz(size)); + } if (align < min_align) + { align = min_align; + } return FUsbMempAllocateTag(instance, size, align, file, line, msg); } @@ -163,12 +175,12 @@ static FError FXhciHandShake(FXhci *xhci, FXhciHandShakeType type, uintptr reg_o switch (type) { - case FXHCI_OP_REG: - ret = FXhciWaitOper32(&xhci->mmio, reg_off, mask, wait_for, timeout); - break; - default: - FASSERT(0); - break; + case FXHCI_OP_REG: + ret = FXhciWaitOper32(&xhci->mmio, reg_off, mask, wait_for, timeout); + break; + default: + FASSERT(0); + break; } return ret; @@ -183,13 +195,17 @@ static FError FXhciHandShake(FXhci *xhci, FXhciHandShakeType type, uintptr reg_o static FError FXhciWaitReady(FXhci *const xhci) { FASSERT(xhci); - FUSB_INFO("Waiting for controller to be ready... "); + FUSB_INFO("Waiting for controller to be ready."); FError ret = FXhciHandShake(xhci, FXHCI_OP_REG, FXHCI_REG_OP_USBSTS, FXHCI_REG_OP_USBSTS_CNR, 0, FXHCI_TIMEOUT); if (FUSB_SUCCESS == ret) - FUSB_INFO("ok"); + { + FUSB_INFO("Waiting for controller success."); + } else - FUSB_ERROR("timeout."); + { + FUSB_ERROR("Waiting for controller timeout."); + } return ret; } @@ -210,12 +226,12 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) u16 hc_version; uintptr xhci_base_addr = base_addr + FUSB3_XHCI_OFFSET; - FUSB_DEBUG("xhci base addr: 0x%x", xhci_base_addr); + FUSB_DEBUG("Xhci base addr: 0x%x.", xhci_base_addr); /* First, allocate and initialize static controller structures */ FUsbHc *const controller = FUsbAllocateHc(instance); if (NULL == controller) { - FUSB_ERROR("Out of memory "); + FUSB_ERROR("Out of memory."); return NULL; } @@ -241,7 +257,7 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) controller->instance = FUSB_ALLOCATE(instance, sizeof(FXhci), FUSB_DEFAULT_ALIGN); if (NULL == controller->instance) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_controller; } @@ -261,9 +277,9 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) xhci->er.ring = FXHCI_ALIGN(xhci, 64, FXHCI_EVENT_RING_SIZE * sizeof(FXhciTrb)); xhci->ev_ring_table = FXHCI_ALIGN(xhci, 64, sizeof(FXhciErstEntry)); if ((NULL == xhci->roothub) || (NULL == xhci->cr.ring) || - (NULL == xhci->er.ring) || (NULL == xhci->ev_ring_table)) + (NULL == xhci->er.ring) || (NULL == xhci->ev_ring_table)) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_xhci; } @@ -275,7 +291,7 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) hc_version = FXhciReadHcVersion(mmio); if (hc_version < FXHCI_HC_VERSION_MIN || hc_version > FXHCI_HC_VERSION_MAX) { - FUSB_ERROR("xHCI version 0x%x not support", hc_version); + FUSB_ERROR("Xhci version 0x%x not support.", hc_version); goto _free_xhci; } @@ -304,7 +320,7 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) xhci->dev = FUSB_ALLOCATE(instance, (xhci->max_slots_en + 1) * sizeof(*xhci->dev), FUSB_DEFAULT_ALIGN); if ((NULL == xhci->dcbaa) || (NULL == xhci->dev)) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_xhci; } @@ -314,17 +330,17 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) */ reg_val = FXhciReadCap32(&xhci->mmio, FXHCI_REG_CAP_HCSPARAMS2); const size_t max_sp_bufs = FXHCI_REG_CAP_HCSPARAMS2_MAX_SCRATCHPAD_BUFS_GET(reg_val); - FUSB_INFO("max scratchpad bufs: 0x%lx reg_val : 0x%x", max_sp_bufs, reg_val); + FUSB_INFO("Max scratchpad bufs: 0x%lx reg_val : 0x%x.", max_sp_bufs, reg_val); if (0 < max_sp_bufs) { - FUSB_INFO("allocate sp_ptrs"); + FUSB_INFO("Allocate sp_ptrs."); const size_t sp_ptrs_size = max_sp_bufs * sizeof(u64); /* allocate scratchpad bufs entry to preserve pointers of scratchpad buf */ FASSERT(NULL == xhci->sp_ptrs); xhci->sp_ptrs = FXHCI_ALIGN(xhci, 64, sp_ptrs_size); if (NULL == xhci->sp_ptrs) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_xhci_structs; } @@ -334,7 +350,7 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) void *const page = FUSB_ALLOCATE(instance, pagesize, pagesize); if (NULL == page) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_xhci_structs; } @@ -346,7 +362,9 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) /* Now start working on the hardware */ if (FUSB_SUCCESS != FXhciWaitReady(xhci)) + { goto _free_xhci_structs; + } /* TODO: Check if BIOS claims ownership (and hand over) */ @@ -362,7 +380,7 @@ FUsbHc *FXhciHcInit(FUsb *instance, uintptr base_addr) xhci->roothub->init = FXhciRootHubInit; xhci->roothub->init(xhci->roothub); - FUSB_INFO("init xHc@%p success", controller); + FUSB_INFO("Init xhc@%p success.", controller); return controller; _free_xhci_structs: @@ -371,7 +389,9 @@ _free_xhci_structs: for (i = 0; (size_t)i < max_sp_bufs; ++i) { if (xhci->sp_ptrs[i]) + { FUSB_FREE(instance, (void *)(uintptr)(xhci->sp_ptrs[i])); + } } } FUSB_FREE(instance, xhci->sp_ptrs); @@ -439,7 +459,9 @@ static void FXhciReinit(FUsbHc *controller) /* wait xhci ready */ if (FUSB_SUCCESS != FXhciWaitReady(xhci)) + { return; + } /* Enable all available slots */ reg_val = FXhciReadOper32(&xhci->mmio, FXHCI_REG_OP_CONFIG); @@ -496,10 +518,10 @@ static void FXhciReinit(FUsbHc *controller) /* run Cmd Nop to test if command ring okay */ for (int i = 0; i < 3; ++i) { - FUSB_INFO("NOOP run #%d ", i); + FUSB_INFO("Noop run #%d .", i); if (FXHCI_CC_SUCCESS != FXhciCmdNop(xhci)) { - FUSB_ERROR("noop command failed. "); + FUSB_ERROR("Noop command failed. "); break; } } @@ -519,7 +541,9 @@ static void FXhciShutdown(FUsbHc *const controller) u32 reg_val; if (controller == NULL) + { return; + } /* detach the Hc instance */ FUsbDetachHc(controller); @@ -537,7 +561,9 @@ static void FXhciShutdown(FUsbHc *const controller) for (i = 0; (size_t)i < max_sp_bufs; ++i) { if (NULL != (void *)(uintptr)xhci->sp_ptrs[i]) + { FUSB_FREE(instance, (void *)(uintptr)(xhci->sp_ptrs[i])); + } } } @@ -630,7 +656,7 @@ static FError FXhciResetEp(FUsbDev *const dev, FUsbEndpoint *const ep) const FXhciTransCode cc = FXhciCmdResetEp(xhci, slot_id, ep_id); if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Reset Endpoint Command failed: %d ", cc); + FUSB_INFO("Reset endpoint command failed: %d .", cc); return FUSB_ERR_TRANS_FAIL; } } @@ -638,7 +664,7 @@ static FError FXhciResetEp(FUsbDev *const dev, FUsbEndpoint *const ep) /* Clear TT buffer for bulk and control endpoints behind a TT */ const int hub = dev->hub; if (hub && dev->speed < FUSB_HIGH_SPEED && - dev->controller->devices[hub]->speed == FUSB_HIGH_SPEED) + dev->controller->devices[hub]->speed == FUSB_HIGH_SPEED) { /* TODO */; } @@ -653,7 +679,7 @@ static FError FXhciResetEp(FUsbDev *const dev, FUsbEndpoint *const ep) tr->ring, 1); if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Set TR Dequeue Command failed: %d ", cc); + FUSB_INFO("Set TR dequeue command failed: %d .", cc); return FUSB_ERR_TRANS_FAIL; } @@ -682,7 +708,7 @@ static void FXhciEnqueueTrb(FXhciTransRing *const tr) while (FXHCI_TRB_GET(TT, tr->cur) == FXHCI_TRB_LINK) { - FUSB_DEBUG("Handling LINK pointer "); + FUSB_DEBUG("Handling link pointer. "); const int tc = FXHCI_TRB_GET(TC, tr->cur); FXHCI_TRB_SET(CH, tr->cur, chain); /* Chain Bit */ @@ -694,7 +720,9 @@ static void FXhciEnqueueTrb(FXhciTransRing *const tr) /* toggle cycle state */ if (tc) + { tr->pcs ^= 1; + } } return; @@ -955,7 +983,7 @@ static FXhciTransCode FXhciBulk(FUsbEndpoint *const ep, const int size, u8 *cons const size_t off = (size_t)data & 0xffff; if ((off + size) > ((FXHCI_TRANSFER_RING_SIZE - 2) << 16)) { - FUSB_INFO("Unsupported transfer size "); + FUSB_INFO("Unsupported transfer size ."); return FXHCI_CC_GENERAL_ERROR; } @@ -964,7 +992,9 @@ static FXhciTransCode FXhciBulk(FUsbEndpoint *const ep, const int size, u8 *cons if (ep_state > FXHCI_EC_STATE_RUNNING) { if (FUSB_SUCCESS != FXhciResetEp(ep->dev, ep)) + { return FXHCI_CC_GENERAL_ERROR; + } } FCacheDCacheInvalidateRange((uintptr)data, size); @@ -1014,7 +1044,9 @@ static FXhciTrb *FXhciNextTrb(FXhciTrb *cur, int *const pcs) while (FXHCI_TRB_GET(TT, cur) == FXHCI_TRB_LINK) { if (pcs && FXHCI_TRB_GET(TC, cur)) + { *pcs ^= 1; + } cur = (void *)(uintptr)(cur->ptr_low); } @@ -1047,20 +1079,20 @@ static void *FXhciCreateIntrQueue(FUsbEndpoint *const ep, const int reqsize, con if (reqcount > (FXHCI_TRANSFER_RING_SIZE - 2)) { - FUSB_INFO("reqcount is too high, at most %d supported ", + FUSB_INFO("Reqcount is too high, at most %d supported .", FXHCI_TRANSFER_RING_SIZE - 2); return NULL; } if (reqsize > 0x10000) { - FUSB_INFO("reqsize is too large, at most 64KiB supported "); + FUSB_INFO("Reqsize is too large, at most 64KiB supported ."); return NULL; } if (xhci->dev[slot_id].interrupt_queues[ep_id]) { - FUSB_INFO("Only one interrupt queue per endpoint supported "); + FUSB_INFO("Only one interrupt queue per endpoint supported ."); return NULL; } @@ -1068,7 +1100,7 @@ static void *FXhciCreateIntrQueue(FUsbEndpoint *const ep, const int reqsize, con FXhciIntrQ *const intrq = FUSB_ALLOCATE(instance, sizeof(*intrq), FUSB_DEFAULT_ALIGN); if (NULL == intrq) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); return NULL; } @@ -1079,7 +1111,7 @@ static void *FXhciCreateIntrQueue(FUsbEndpoint *const ep, const int reqsize, con { if (FXHCI_TRB_GET(C, cur) == (unsigned int)pcs) { - FUSB_INFO("Not enough empty TRBs "); + FUSB_INFO("Not enough empty TRBs ."); goto _free_return; } @@ -1087,7 +1119,7 @@ static void *FXhciCreateIntrQueue(FUsbEndpoint *const ep, const int reqsize, con void *const reqdata = FXHCI_ALIGN(xhci, 1, reqsize); if (NULL == reqdata) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_return; } @@ -1112,7 +1144,9 @@ static void *FXhciCreateIntrQueue(FUsbEndpoint *const ep, const int reqsize, con /* Now enqueue all the prepared TRBs but the last and ring the doorbell. */ for (i = 0; i < (reqcount - 1); ++i) + { FXhciEnqueueTrb(tr); + } FXhciRingDoorbell(ep); return intrq; @@ -1152,7 +1186,9 @@ static void FXhciDestoryIntrQueue(FUsbEndpoint *const ep, void *const q) { const FXhciTransCode cc = FXhciCmdStopEp(xhci, slot_id, ep_id); if (cc != FXHCI_CC_SUCCESS) - FUSB_INFO("Warning: Failed to stop endpoint "); + { + FUSB_INFO("Warning: Failed to stop endpoint ."); + } } /* Process all remaining transfer events */ @@ -1188,7 +1224,9 @@ static void FXhciDestoryIntrQueue(FUsbEndpoint *const ep, void *const q) static u8 *FXhciPollIntrQueue(void *const q) { if (NULL == q) + { return NULL; + } FXhciIntrQ *const intrq = (FXhciIntrQ *)q; FUsbEndpoint *const ep = intrq->ep; @@ -1224,15 +1262,21 @@ static u8 *FXhciPollIntrQueue(void *const q) /* Check if anything was transferred */ const size_t read = FXHCI_TRB_GET(TL, intrq->next); if (!read) + { reqdata = NULL; + } else if (read < intrq->size) /* At least zero it, poll interface is rather limited */ + { memset(reqdata + read, 0x00, intrq->size - read); + } /* Advance the interrupt queue */ if (intrq->ready == intrq->next) /* This was last TRB being ready */ + { intrq->ready = NULL; + } intrq->next = FXhciNextTrb(intrq->next, NULL); } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.h b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.h index b23ebd05a1..9221bb352b 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci.h @@ -19,20 +19,21 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_USB_FXHCI_H -#define DRIVERS_USB_FXHCI_H +#ifndef FXHCI_H +#define FXHCI_H + +/***************************** Include Files *********************************/ +#include "fusb.h" + #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include "fusb.h" - /************************** Constant Definitions *****************************/ #define FXHCI_EVENT_RING_SIZE 64 #define FXHCI_TRANSFER_RING_SIZE 32 /* Never raise this above 256 to prevent transfer event length overflow! */ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_cmd.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_cmd.c index dbfb2780da..a25961bf66 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_cmd.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_cmd.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fdebug.h" @@ -39,7 +39,7 @@ FXhciTrb *FXhciNextCmdTrb(FXhci *const xhci) void FXhciPostCmd(FXhci *const xhci) { - FUSB_INFO("Command %d (@%p) ", FXHCI_TRB_GET(TT, xhci->cr.cur), xhci->cr.cur); + FUSB_INFO("Command %d (@%p).", FXHCI_TRB_GET(TT, xhci->cr.cur), xhci->cr.cur); FXHCI_TRB_SET(C, xhci->cr.cur, xhci->cr.pcs); /* Cycle Bit */ ++xhci->cr.cur; @@ -52,12 +52,14 @@ void FXhciPostCmd(FXhci *const xhci) while (FXHCI_TRB_GET(TT, xhci->cr.cur) == FXHCI_TRB_LINK) { - FUSB_DEBUG("Handling LINK pointer (@%p) ", xhci->cr.cur); + FUSB_DEBUG("Handling link pointer (@%p).", xhci->cr.cur); const int tc = FXHCI_TRB_GET(TC, xhci->cr.cur); /* Completion Code */ FXHCI_TRB_SET(C, xhci->cr.cur, xhci->cr.pcs); /* Cycle Bit */ xhci->cr.cur = (void *)(uintptr)(xhci->cr.cur->ptr_low); if (tc) + { xhci->cr.pcs ^= 1; + } } } @@ -70,10 +72,12 @@ static FXhciTransCode FXhciWaitForCmd(FXhci *const xhci, cc = FXhciWaitForCmdDone(xhci, cmd_trb, clear_event); if (cc != FXHCI_CC_TIMEOUT) + { return cc; + } /* Abort command on timeout */ - FUSB_ERROR("Aborting command (@%p), CRCR: 0x%x ", cmd_trb, FXhciReadOper64(&xhci->mmio, FXHCI_REG_OP_CRCR)); + FUSB_ERROR("Aborting command (@%p), CRCR: 0x%x.", cmd_trb, FXhciReadOper64(&xhci->mmio, FXHCI_REG_OP_CRCR)); /* * Ref. xHCI Specification Revision 1.2, May 2019. @@ -88,7 +92,9 @@ static FXhciTransCode FXhciWaitForCmd(FXhci *const xhci, cc = FXhciWaitForCmdAborted(xhci, cmd_trb); if ((FXhciReadOper64(&xhci->mmio, FXHCI_REG_OP_CRCR) & FXHCI_REG_OP_CRCR_CRR)) - FUSB_ERROR("xhci_wait_for_command: Command ring still running"); + { + FUSB_ERROR("FXhciWaitForCmd: Command ring still running."); + } return cc; } @@ -103,12 +109,14 @@ FXhciTransCode FXhciCmdNop(FXhci *const xhci) /* wait for result in event ring */ FXhciTransCode cc = FXhciWaitForCmdDone(xhci, cmd, 1); - FUSB_INFO("Command ring is %srunning: cc: %d", + FUSB_INFO("Command ring is %srunning: cc: %d.", (FXhciReadOper64(&xhci->mmio, FXHCI_REG_OP_CRCR) & FXHCI_REG_OP_CRCR_CRR) ? "" : "not ", /* check if cmd ring is running */ cc); if (cc != FXHCI_CC_SUCCESS) - FUSB_ERROR("noop command failed. "); + { + FUSB_ERROR("Noop command failed."); + } return cc; } @@ -131,7 +139,9 @@ FXhciTransCode FXhciCmdEnableSlot(FXhci *const xhci, int *const slot_id) { *slot_id = FXHCI_TRB_GET(ID, xhci->er.cur); if (*slot_id > xhci->max_slots_en) + { cc = FXHCI_CC_CONTROLLER_ERROR; + } } FXhciAdvanceEvtRing(xhci); @@ -178,7 +188,9 @@ FXhciTransCode FXhciCmdConfigureEp(FXhci *const xhci, cmd->ptr_low = (uintptr)(ic->raw); if (config_id == 0) - FXHCI_TRB_SET(DC, cmd, 1); /* Deconfigure */ + { + FXHCI_TRB_SET(DC, cmd, 1); /* Deconfigure */ + } FXhciPostCmd(xhci); diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_debug.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_debug.c index 027a7f4390..13663444ec 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_debug.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_debug.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include @@ -77,12 +77,16 @@ void FXhciDumpDevCtx(const FXhciDevCtx *const dc, const u32 ctx_mask) unsigned int i; if (ctx_mask & 1) + { FXhciDumpSlotCtx(dc->slot); + } for (i = 1; i <= FXHCI_SC_GET(CTXENT, dc->slot); ++i) { if (ctx_mask & (1 << i)) + { FXhciDumpEpCtx(dc->ep[i]); + } } } @@ -114,9 +118,13 @@ void FXhciDumpTransferTrb(const FXhciTrb *const cur) static const FXhciTrb *FXhciNextTrb(const FXhciTrb *const cur) { if (FXHCI_TRB_GET(TT, cur) == FXHCI_TRB_LINK) + { return (!cur->ptr_low) ? NULL : (void *)(uintptr)(cur->ptr_low); + } else + { return cur + 1; + } } void FXhciDumpTransferTrbs(const FXhciTrb *const first, const FXhciTrb *const last) @@ -126,6 +134,8 @@ void FXhciDumpTransferTrbs(const FXhciTrb *const first, const FXhciTrb *const la { FXhciDumpTransferTrb(cur); if (cur == last) + { break; + } } } diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_dev.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_dev.c index 3d1b868c85..e284bf6bdc 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_dev.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_dev.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include @@ -39,7 +39,9 @@ static u32 FXhciGenRounte(FXhci *const xhci, const int hubport, const int hubadd { FASSERT(xhci); if (!hubaddr) + { return 0; + } u32 route_string = FXHCI_SC_GET(ROUTE, xhci->dev[hubaddr].ctx.slot); int i; @@ -60,7 +62,9 @@ static int FXhciGetRoothubPort(FXhci *const xhci, const int hubport, const int h { FASSERT(xhci); if (!hubaddr) + { return hubport; + } return FXHCI_SC_GET(RHPORT, xhci->dev[hubaddr].ctx.slot); } @@ -71,7 +75,9 @@ static int FXhciGetTT(FXhci *const xhci, const FUsbSpeed speed, { FASSERT(xhci); if (!hubaddr) + { return 0; + } const FXhciSlotCtx *const slot = xhci->dev[hubaddr].ctx.slot; @@ -95,21 +101,31 @@ static void FXhciReapSlots(FXhci *const xhci, int skip_slot) int i; FUsb *instance = xhci->usb; - FUSB_INFO("xHC resource shortage, trying to reap old slots... "); + FUSB_INFO("Xhci resource shortage, trying to reap old slots."); for (i = 1; i <= xhci->max_slots_en; i++) { if (i == skip_slot) - continue; /* don't reap slot we were working on */ + { + continue; /* don't reap slot we were working on */ + } if (xhci->dev[i].transfer_rings[1]) - continue; /* slot still in use */ + { + continue; /* slot still in use */ + } if (NULL == xhci->dev[i].ctx.raw) - continue; /* slot already disabled */ + { + continue; /* slot already disabled */ + } const FXhciTransCode cc = FXhciCmdDisableSlot(xhci, i); if (cc != FXHCI_CC_SUCCESS) - FUSB_INFO("Failed to disable slot %d: %d ", i, cc); + { + FUSB_INFO("Failed to disable slot %d: %d.", i, cc); + } else - FUSB_INFO("Successfully reaped slot %d ", i); + { + FUSB_INFO("Successfully reaped slot %d.", i); + } xhci->dcbaa[i] = 0; FUSB_FREE(instance, xhci->dev[i].ctx.raw); @@ -138,7 +154,9 @@ static FXhciInputCtx *FXhciMakeInputCtx(FXhci *xhci, const size_t ctxsize) ic->add = dma_buffer + 4; dma_buffer += ctxsize; for (i = 0; i < FXHCI_NUM_EPS; i++, dma_buffer += ctxsize) + { ic->dev.ep[i] = dma_buffer; + } return ic; } @@ -173,7 +191,7 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h if ((NULL == ic) || (NULL == tr) || (NULL == tr->ring)) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); goto _free_return; } @@ -188,22 +206,26 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Enable slot failed: %d ", cc); + FUSB_INFO("Enable slot failed: %d.", cc); goto _free_return; } else { - FUSB_INFO("Enabled slot %d ", slot_id); + FUSB_INFO("Enabled slot %d.", slot_id); } di = &xhci->dev[slot_id]; void *dma_buffer = FUSB_ALLOCATE(instance, FXHCI_NUM_EPS * ctxsize, 64); if (NULL == dma_buffer) + { goto _disable_return; + } memset(dma_buffer, 0, FXHCI_NUM_EPS * ctxsize); for (i = 0; i < FXHCI_NUM_EPS; i++, dma_buffer += ctxsize) + { di->ctx.ep[i] = dma_buffer; + } *ic->add = (1 << 0) /* Slot Context */ | (1 << 1) /* EP0 Context */; @@ -215,7 +237,7 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h int tt, tt_port; if (FXhciGetTT(xhci, speed, hubport, hubaddr, &tt, &tt_port)) { - FUSB_INFO("TT for %d: %d[%d] ", slot_id, tt, tt_port); + FUSB_INFO("TT for %d: %d[%d].", slot_id, tt, tt_port); FXHCI_SC_SET(MTT, ic->dev.slot, FXHCI_SC_GET(MTT, xhci->dev[tt].ctx.slot)); FXHCI_SC_SET(TTID, ic->dev.slot, tt); FXHCI_SC_SET(TTPORT, ic->dev.slot, tt_port); @@ -245,12 +267,12 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Address device failed: %d ", cc); + FUSB_INFO("Address device failed: %d.", cc); goto _disable_return; } else { - FUSB_INFO("Addressed device %d (USB: %d) ", + FUSB_INFO("Addressed device %d (USB: %d).", slot_id, FXHCI_SC_GET(UADDR, di->ctx.slot)); } @@ -258,7 +280,9 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h dev = FUsbInitDevEntry(controller, slot_id); if (!dev) + { goto _disable_return; + } dev->address = slot_id; dev->hub = hubaddr; @@ -273,7 +297,7 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h u8 buf[8]; if (FUsbGetDescriptor(dev, FUsbGenerateReqType(FUSB_REQ_DEVICE_TO_HOST, FUSB_REQ_TYPE_STANDARD, FUSB_REQ_RECP_DEV), FUSB_DESC_TYPE_DEVICE, 0, buf, sizeof(buf)) != sizeof(buf)) { - FUSB_INFO("first FUsbGetDescriptor(FUSB_DESC_TYPE_DEVICE) failed "); + FUSB_INFO("First FUsbGetDescriptor(FUSB_DESC_TYPE_DEVICE) failed."); goto _disable_return; } @@ -295,7 +319,7 @@ FUsbDev *FXhciSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int h } if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Context evaluation failed: %d ", cc); + FUSB_INFO("Context evaluation failed: %d.", cc); goto _disable_return; } } @@ -309,7 +333,9 @@ _disable_return: dev = NULL; _free_return: if (tr) + { FUSB_FREE(instance, (void *)tr->ring); + } FUSB_FREE(instance, tr); if (di) { @@ -332,7 +358,7 @@ static int FXhciFinishHubConfig(FUsbDev *const dev, FXhciInputCtx *const ic) if (FUsbGetDescriptor(dev, FUsbGenerateReqType(FUSB_REQ_DEVICE_TO_HOST, FUSB_REQ_TYPE_CLASS, FUSB_REQ_RECP_DEV), type, 0, &desc, sizeof(desc)) != sizeof(desc)) { - FUSB_INFO("Failed to fetch hub descriptor "); + FUSB_INFO("Failed to fetch hub descriptor."); return FXHCI_CC_COMMUNICATION_ERROR; } @@ -350,26 +376,38 @@ static int FXhciFinishHubConfig(FUsbDev *const dev, FXhciInputCtx *const ic) static size_t FXhciBoundInterval(const FUsbEndpoint *const ep) { if ((ep->dev->speed == FUSB_LOW_SPEED && - (ep->type == FUSB_ISOCHRONOUS_EP || - ep->type == FUSB_INTERRUPT_EP)) || - (ep->dev->speed == FUSB_FULL_SPEED && - ep->type == FUSB_INTERRUPT_EP)) + (ep->type == FUSB_ISOCHRONOUS_EP || + ep->type == FUSB_INTERRUPT_EP)) || + (ep->dev->speed == FUSB_FULL_SPEED && + ep->type == FUSB_INTERRUPT_EP)) { if (ep->interval < 3) + { return 3; + } else if (ep->interval > 11) + { return 11; + } else + { return ep->interval; + } } else { if (ep->interval < 0) + { return 0; + } else if (ep->interval > 15) + { return 15; + } else + { return ep->interval; + } } } @@ -379,10 +417,12 @@ static int FXhciFinishEpConfig(const FUsbEndpoint *const ep, FXhciInputCtx *cons FASSERT(xhci); FUsb *instance = xhci->usb; const int ep_id = FXhciEpId(ep); - FUSB_INFO("ep_id: %d ", ep_id); + FUSB_INFO("ep_id: %d.", ep_id); if (ep_id <= 1 || 32 <= ep_id) + { return FXHCI_CC_DRIVER_ERROR; + } FXhciTransRing *const tr = FUSB_ALLOCATE(instance, sizeof(*tr), FUSB_DEFAULT_ALIGN); if (NULL != tr) @@ -394,7 +434,7 @@ static int FXhciFinishEpConfig(const FUsbEndpoint *const ep, FXhciInputCtx *cons if ((NULL == tr) || (NULL == tr->ring)) { FUSB_FREE(instance, tr); - FUSB_ERROR("Out of memory "); + FUSB_ERROR("Out of memory."); return FXHCI_CC_OUT_OF_MEMORY; } @@ -403,11 +443,13 @@ static int FXhciFinishEpConfig(const FUsbEndpoint *const ep, FXhciInputCtx *cons *ic->add |= (1 << ep_id); if ((int)FXHCI_SC_GET(CTXENT, ic->dev.slot) < ep_id) + { FXHCI_SC_SET(CTXENT, ic->dev.slot, ep_id); + } FXhciEpCtx *const epctx = ic->dev.ep[ep_id]; - FUSB_DEBUG("Filling epctx (@%p) ", epctx); + FUSB_DEBUG("Filling epctx (@%p).", epctx); epctx->tr_dq_low = (uintptr)(tr->ring); epctx->tr_dq_high = 0; @@ -420,16 +462,16 @@ static int FXhciFinishEpConfig(const FUsbEndpoint *const ep, FXhciInputCtx *cons size_t avrtrb; switch (ep->type) { - case FUSB_BULK_EP: - case FUSB_ISOCHRONOUS_EP: - avrtrb = 3 * 1024; - break; - case FUSB_INTERRUPT_EP: - avrtrb = 1024; - break; - default: - avrtrb = 8; - break; + case FUSB_BULK_EP: + case FUSB_ISOCHRONOUS_EP: + avrtrb = 3 * 1024; + break; + case FUSB_INTERRUPT_EP: + avrtrb = 1024; + break; + default: + avrtrb = 8; + break; } FXHCI_EC_SET(AVRTRB, epctx, avrtrb); FXHCI_EC_SET(MXESIT, epctx, FXHCI_EC_GET(MPS, epctx) * FXHCI_EC_GET(MBS, epctx)); @@ -457,7 +499,7 @@ FXhciTransCode FXhciFinishDevConfig(FUsbDev *const dev) FXhciInputCtx *const ic = FXhciMakeInputCtx(xhci, FXhciGetCtxSize(&xhci->mmio)); if (!ic) { - FUSB_INFO("Out of memory "); + FUSB_INFO("Out of memory."); return FXHCI_CC_OUT_OF_MEMORY; } @@ -474,14 +516,18 @@ FXhciTransCode FXhciFinishDevConfig(FUsbDev *const dev) { ret = FXhciFinishHubConfig(dev, ic); if (ret) + { goto _free_return; + } } for (i = 1; i < dev->num_endp; ++i) { ret = FXhciFinishEpConfig(&dev->endpoints[i], ic); if (ret) + { goto _free_ep_ctx_return; + } } const int config_id = dev->configuration->bConfigurationValue; @@ -496,13 +542,13 @@ FXhciTransCode FXhciFinishDevConfig(FUsbDev *const dev) if (cc != FXHCI_CC_SUCCESS) { - FUSB_INFO("Configure endpoint failed: %d ", cc); + FUSB_INFO("Configure endpoint failed: %d.", cc); ret = FXHCI_CC_CONTROLLER_ERROR; goto _free_ep_ctx_return; } else { - FUSB_INFO("Endpoints configured "); + FUSB_INFO("Endpoints configured."); } goto _free_return; @@ -540,7 +586,9 @@ void FXhciDestoryDev(FUsbHc *const controller, const int slot_id) FUsb *instance = xhci->usb; if (slot_id <= 0 || slot_id > xhci->max_slots_en) + { return; + } FXhciInputCtx *const ic = FXhciMakeInputCtx(xhci, FXhciGetCtxSize(&xhci->mmio)); if (NULL == ic) @@ -565,11 +613,15 @@ void FXhciDestoryDev(FUsbHc *const controller, const int slot_id) } if (cc != FXHCI_CC_SUCCESS) - FUSB_INFO("Failed to quiesce slot %d: %d ", slot_id, cc); + { + FUSB_INFO("Failed to quiesce slot %d: %d.", slot_id, cc); + } cc = FXhciCmdStopEp(xhci, slot_id, FXHCI_EP0_ID); if (cc != FXHCI_CC_SUCCESS) - FUSB_INFO("Failed to stop EP0 on slot %d: %d ", slot_id, cc); + { + FUSB_INFO("Failed to stop EP0 on slot %d: %d.", slot_id, cc); + } int i; FXhciDevInfo *const di = &xhci->dev[slot_id]; @@ -590,7 +642,7 @@ void FXhciDestoryDev(FUsbHc *const controller, const int slot_id) di->ctx.raw = NULL; } - FUSB_INFO("Stopped slot %d, but not disabling it yet. ", slot_id); + FUSB_INFO("Stopped slot %d, but not disabling it yet.", slot_id); di->transfer_rings[1] = NULL; return; diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_evt.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_evt.c index cfa984ed6a..0995b6eeef 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_evt.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_evt.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fsleep.h" @@ -43,7 +43,9 @@ void FXhciResetEvtRing(FXhciEvtRing *const er) { int i; for (i = 0; i < FXHCI_EVENT_RING_SIZE; ++i) + { er->ring[i].control &= ~FXHCI_TRB_CYCLE; + } er->cur = er->ring; er->last = er->ring + FXHCI_EVENT_RING_SIZE; er->ccs = 1; @@ -59,7 +61,7 @@ void FXhciUpdateEvtDQ(FXhci *const xhci) { if (xhci->er.adv) { - FUSB_DEBUG("Updating dq ptr: @0x%lx -> %p", + FUSB_DEBUG("Updating dq ptr: @0x%lx -> %p.", FXhciReadRt64(&xhci->mmio, 0, FXHCI_REG_RT_IR_ERDP), xhci->er.cur); FXhciWriteRt64(&xhci->mmio, 0, FXHCI_REG_RT_IR_ERDP, FXHCI_REG_RT_IR_ERDP_MASK & ((u64)(uintptr)xhci->er.cur)); @@ -73,7 +75,7 @@ void FXhciAdvanceEvtRing(FXhci *const xhci) xhci->er.adv = 1; if (xhci->er.cur == xhci->er.last) { - FUSB_DEBUG("Roll over in event ring "); + FUSB_DEBUG("Roll over in event ring."); xhci->er.cur = xhci->er.ring; xhci->er.ccs ^= 1; FXhciUpdateEvtDQ(xhci); @@ -91,7 +93,7 @@ static void FXhciHandleTransferEvt(FXhci *const xhci) FXhciIntrQ *intrq; if (id && id <= xhci->max_slots_en && - (intrq = xhci->dev[id].interrupt_queues[ep])) + (intrq = xhci->dev[id].interrupt_queues[ep])) { /* It's a running interrupt endpoint */ intrq->ready = (void *)(uintptr)(ev->ptr_low); @@ -102,7 +104,7 @@ static void FXhciHandleTransferEvt(FXhci *const xhci) } else { - FUSB_INFO("Interrupt Transfer failed: %d ", cc); + FUSB_INFO("Interrupt transfer failed: %d.", cc); FXHCI_TRB_SET(TL, intrq->ready, 0); /* Transfer Length */ } } @@ -146,22 +148,22 @@ static void FXhciHandleHostCtrlEvt(FXhci *const xhci) const FXhciTransCode cc = FXHCI_TRB_GET(CC, ev); switch (cc) { - case FXHCI_CC_EVENT_RING_FULL_ERROR: - FUSB_INFO("Event ring full! (@%p) ", xhci->er.cur); - /* - * If we get here, we have processed the whole queue: - * xHC pushes this event, when it sees the ring full, - * full of other events. - * IMO it's save and necessary to update the dequeue - * pointer here. - */ - FXhciAdvanceEvtRing(xhci); - FXhciUpdateEvtDQ(xhci); - break; - default: - FUSB_INFO("Warning: Spurious host controller event: %d ", cc); - FXhciAdvanceEvtRing(xhci); - break; + case FXHCI_CC_EVENT_RING_FULL_ERROR: + FUSB_INFO("Event ring full! (@%p).", xhci->er.cur); + /* + * If we get here, we have processed the whole queue: + * xHC pushes this event, when it sees the ring full, + * full of other events. + * IMO it's save and necessary to update the dequeue + * pointer here. + */ + FXhciAdvanceEvtRing(xhci); + FXhciUpdateEvtDQ(xhci); + break; + default: + FUSB_INFO("Warning: spurious host controller event: %d.", cc); + FXhciAdvanceEvtRing(xhci); + break; } } @@ -178,35 +180,37 @@ static void FXhciHandleEvt(FXhci *const xhci) const int trb_type = FXHCI_TRB_GET(TT, ev); switch (trb_type) { - /* Either pass along the event or advance event ring */ - case FXHCI_TRB_EV_TRANSFER: - FXhciHandleTransferEvt(xhci); - break; - case FXHCI_TRB_EV_CMD_CMPL: - FXhciHandleCmdCompletionEvt(xhci); - break; - case FXHCI_TRB_EV_PORTSC: - FUSB_INFO("Port Status Change Event for %d: %d ", - FXHCI_TRB_GET(PORT, ev), FXHCI_TRB_GET(CC, ev)); - /* We ignore the event as we look for the PORTSC - registers instead, at a time when it suits _us_. */ - FXhciAdvanceEvtRing(xhci); - break; - case FXHCI_TRB_EV_HOST: - FXhciHandleHostCtrlEvt(xhci); - break; - default: - FUSB_INFO("Warning: Spurious event: %d, Completion Code: %d ", - trb_type, FXHCI_TRB_GET(CC, ev)); - FXhciAdvanceEvtRing(xhci); - break; + /* Either pass along the event or advance event ring */ + case FXHCI_TRB_EV_TRANSFER: + FXhciHandleTransferEvt(xhci); + break; + case FXHCI_TRB_EV_CMD_CMPL: + FXhciHandleCmdCompletionEvt(xhci); + break; + case FXHCI_TRB_EV_PORTSC: + FUSB_INFO("Port status change event for %d: %d. ", + FXHCI_TRB_GET(PORT, ev), FXHCI_TRB_GET(CC, ev)); + /* We ignore the event as we look for the PORTSC + registers instead, at a time when it suits _us_. */ + FXhciAdvanceEvtRing(xhci); + break; + case FXHCI_TRB_EV_HOST: + FXhciHandleHostCtrlEvt(xhci); + break; + default: + FUSB_INFO("Warning: spurious event: %d, completion code: %d.", + trb_type, FXHCI_TRB_GET(CC, ev)); + FXhciAdvanceEvtRing(xhci); + break; } } void FXhciHandleEvts(FXhci *const xhci) { while (FXhciEvtReady(&xhci->er)) + { FXhciHandleEvt(xhci); + } FXhciUpdateEvtDQ(xhci); return; @@ -230,7 +234,9 @@ static unsigned long FXhciWaitForEvtType(FXhci *const xhci, while (FXhciWaitForEvt(&xhci->er, timeout_us)) { if (FXHCI_TRB_GET(TT, xhci->er.cur) == (unsigned int)trb_type) + { break; + } FXhciHandleEvt(xhci); } @@ -265,7 +271,7 @@ FXhciTransCode FXhciWaitForCmdAborted(FXhci *const xhci, const FXhciTrb *const a while (FXhciWaitForEvtType(xhci, FXHCI_TRB_EV_CMD_CMPL, &timeout_us)) { if ((xhci->er.cur->ptr_low == (uintptr)(address)) && - (xhci->er.cur->ptr_high == 0)) + (xhci->er.cur->ptr_high == 0)) { cc = FXHCI_TRB_GET(CC, xhci->er.cur); FXhciAdvanceEvtRing(xhci); @@ -276,8 +282,7 @@ FXhciTransCode FXhciWaitForCmdAborted(FXhci *const xhci, const FXhciTrb *const a } if (timeout_us == 0) { - FUSB_INFO("Warning: Timed out waiting for " - "COMMAND_ABORTED or COMMAND_RING_STOPPED. "); + FUSB_INFO("Warning: timeout waiting COMMAND_ABORTED or COMMAND_RING_STOPPED."); goto update_and_return; } if (cc == FXHCI_CC_COMMAND_RING_STOPPED) @@ -299,8 +304,7 @@ FXhciTransCode FXhciWaitForCmdAborted(FXhci *const xhci, const FXhciTrb *const a FXhciHandleCmdCompletionEvt(xhci); } if (timeout_us == 0) - FUSB_INFO("Warning: Timed out " - "waiting for COMMAND_RING_STOPPED. "); + FUSB_INFO("Warning: timeout waiting for COMMAND_RING_STOPPED."); update_and_return: FXhciUpdateEvtDQ(xhci); @@ -321,7 +325,7 @@ FXhciTransCode FXhciWaitForCmdDone(FXhci *const xhci, while (FXhciWaitForEvtType(xhci, FXHCI_TRB_EV_CMD_CMPL, &timeout_us)) { if ((xhci->er.cur->ptr_low == (uintptr)(address)) && - (xhci->er.cur->ptr_high == 0)) + (xhci->er.cur->ptr_high == 0)) { cc = FXHCI_TRB_GET(CC, xhci->er.cur); break; @@ -332,7 +336,7 @@ FXhciTransCode FXhciWaitForCmdDone(FXhci *const xhci, if (!timeout_us) { - FUSB_INFO("Warning: Timed out waiting for FXHCI_TRB_EV_CMD_CMPL. "); + FUSB_INFO("Warning: timeout waiting for FXHCI_TRB_EV_CMD_CMPL."); } else if (clear_event) { @@ -352,11 +356,13 @@ FXhciTransCode FXhciWaitForTransfer(FXhci *const xhci, const int slot_id, const while (FXhciWaitForEvtType(xhci, FXHCI_TRB_EV_TRANSFER, &timeout_us)) { if (FXHCI_TRB_GET(ID, xhci->er.cur) == (unsigned int)slot_id && - FXHCI_TRB_GET(EP, xhci->er.cur) == (unsigned int)ep_id) + FXHCI_TRB_GET(EP, xhci->er.cur) == (unsigned int)ep_id) { ret = -FXHCI_TRB_GET(CC, xhci->er.cur); if (ret == -FXHCI_CC_SUCCESS || ret == -FXHCI_CC_SHORT_PACKET) + { ret = FXHCI_TRB_GET(EVTL, xhci->er.cur); + } FXhciAdvanceEvtRing(xhci); break; } @@ -364,7 +370,9 @@ FXhciTransCode FXhciWaitForTransfer(FXhci *const xhci, const int slot_id, const FXhciHandleTransferEvt(xhci); } if (!timeout_us) - FUSB_INFO("Warning: Timed out waiting for FXHCI_TRB_EV_TRANSFER. "); + { + FUSB_INFO("Warning: timeout waiting for FXHCI_TRB_EV_TRANSFER. "); + } FXhciUpdateEvtDQ(xhci); return ret; diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.c index 3af4ad4968..aa06b6e48f 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ /***************************** Include Files *********************************/ @@ -87,77 +87,81 @@ static void FXhciParseExtCap(FXhciMMIO *mmio, const uintptr offset, const u32 ca switch (cap_id) { - case FXHCI_EXT_CAP_ID_USB_LEGACY_SUPPORT: - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBLEGSUP_OFFSET); - FUSB_INFO(" BIOS owned %d OS owned %d", - FXHCI_USBLEGSUP_BIOS_OWNED_SEMAPHORE & reg_val, - FXHCI_USBLEGSUP_OS_OWNED_SEMAPHORE & reg_val); + case FXHCI_EXT_CAP_ID_USB_LEGACY_SUPPORT: + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBLEGSUP_OFFSET); + FUSB_INFO(" BIOS owned %d OS owned %d", + FXHCI_USBLEGSUP_BIOS_OWNED_SEMAPHORE & reg_val, + FXHCI_USBLEGSUP_OS_OWNED_SEMAPHORE & reg_val); - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBLEGCTLSTS_OFFSET); - FUSB_INFO(" SMI ctrl/status 0x%x", reg_val); - break; - case FXHCI_EXT_CAP_ID_SUPPORT_PROTOCOL: - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET); - FUSB_INFO(" Name: %c%c%c%c", - *((char *)®_val), *((char *)®_val + 1), - *((char *)®_val + 2), *((char *)®_val + 3)); + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBLEGCTLSTS_OFFSET); + FUSB_INFO(" SMI ctrl/status 0x%x", reg_val); + break; + case FXHCI_EXT_CAP_ID_SUPPORT_PROTOCOL: + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET); + FUSB_INFO(" Name: %c%c%c%c", + *((char *)®_val), *((char *)®_val + 1), + *((char *)®_val + 2), *((char *)®_val + 3)); - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCF_OFFSET); - major_ver = FXHCI_USBSPCF_MAJOR_REVERSION_GET(reg_val); - minor_ver = FXHCI_USBSPCF_MINOR_REVERSION_GET(reg_val); - FUSB_INFO(" Version: %d.%d", major_ver, minor_ver); + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCF_OFFSET); + major_ver = FXHCI_USBSPCF_MAJOR_REVERSION_GET(reg_val); + minor_ver = FXHCI_USBSPCF_MINOR_REVERSION_GET(reg_val); + FUSB_INFO(" Version: %d.%d", major_ver, minor_ver); - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET); - FUSB_INFO(" Compatible ports: [%d-%d]", - FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val), - FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1); + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET); + FUSB_INFO(" Compatible ports: [%d-%d]", + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val), + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1); - if (FXHCI_MAJOR_REVERSION_USB2 == major_ver) - { - mmio->usb2_ports.port_beg = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val); - mmio->usb2_ports.port_end = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1; + if (FXHCI_MAJOR_REVERSION_USB2 == major_ver) + { + mmio->usb2_ports.port_beg = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val); + mmio->usb2_ports.port_end = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1; - FUSB_INFO(" High-speed only: %d, Integrated hub: %d, Hardware LMP: %d", - FXHCI_USBSPCFDEF2_USB2_HIGH_SPEED_ONLY & reg_val, - FXHCI_USBSPCFDEF2_USB2_INTERGRATED_HUB & reg_val, - FXHCI_USBSPCFDEF2_USB2_HW_LMP_CAP & reg_val); - } - else if (FXHCI_MAJOR_REVERSION_USB3 == major_ver) - { - mmio->usb3_ports.port_beg = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val); - mmio->usb3_ports.port_end = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1; - } + FUSB_INFO(" High-speed only: %d, Integrated hub: %d, Hardware LMP: %d", + FXHCI_USBSPCFDEF2_USB2_HIGH_SPEED_ONLY & reg_val, + FXHCI_USBSPCFDEF2_USB2_INTERGRATED_HUB & reg_val, + FXHCI_USBSPCFDEF2_USB2_HW_LMP_CAP & reg_val); + } + else if (FXHCI_MAJOR_REVERSION_USB3 == major_ver) + { + mmio->usb3_ports.port_beg = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val); + mmio->usb3_ports.port_end = FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(reg_val) + FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(reg_val) - 1; + } - psic = FXHCI_USBSPCFDEF2_PROTOCOL_SPEED_ID_CNT_GET(reg_val); - FUSB_INFO(" PSIC: 0x%x", psic); + psic = FXHCI_USBSPCFDEF2_PROTOCOL_SPEED_ID_CNT_GET(reg_val); + FUSB_INFO(" PSIC: 0x%x", psic); - if (0 != psic) - { - reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_PROTOCOL_SPEED_ID_OFFSET(psic)); + if (0 != psic) + { + reg_val = FXhciReadExtCap32(mmio, offset + FXHCI_REG_PROTOCOL_SPEED_ID_OFFSET(psic)); - FUSB_INFO(" Protocol speed-id: %d^%d", - FXHCI_PROTOCOL_SPEED_ID_VALUE_GET(reg_val), - FXHCI_PROTOCOL_SPEED_ID_EXPONENT_GET(reg_val)); - FUSB_INFO(" PSI type: %d, PSI full-duplex: %d, Mantissa: 0x%x", - FXHCI_PROTOCOL_SPEED_ID_PSI_TYPE_GET(reg_val), - (FXHCI_PROTOCOL_SPEED_ID_PSI_FULL_DUPLEX & reg_val == FXHCI_PROTOCOL_SPEED_ID_PSI_FULL_DUPLEX), - FXHCI_PROTOCOL_SPEED_ID_MANTISSA_GET(reg_val)); - } - else - { - if (FXHCI_MAJOR_REVERSION_USB3 == major_ver) - FUSB_INFO("For USB3, only the default SuperSpeed bit rate is supported !!!"); - else if (FXHCI_MAJOR_REVERSION_USB2 == major_ver) - FUSB_INFO("For USB2, default Full-speed, Low-speed and High-speed bit rate supported !!!"); - } + FUSB_INFO(" Protocol speed-id: %d^%d", + FXHCI_PROTOCOL_SPEED_ID_VALUE_GET(reg_val), + FXHCI_PROTOCOL_SPEED_ID_EXPONENT_GET(reg_val)); + FUSB_INFO(" PSI type: %d, PSI full-duplex: %d, Mantissa: 0x%x", + FXHCI_PROTOCOL_SPEED_ID_PSI_TYPE_GET(reg_val), + (FXHCI_PROTOCOL_SPEED_ID_PSI_FULL_DUPLEX & reg_val == FXHCI_PROTOCOL_SPEED_ID_PSI_FULL_DUPLEX), + FXHCI_PROTOCOL_SPEED_ID_MANTISSA_GET(reg_val)); + } + else + { + if (FXHCI_MAJOR_REVERSION_USB3 == major_ver) + { + FUSB_INFO("For USB3, only the default super speed bit rate is supported !!!"); + } + else if (FXHCI_MAJOR_REVERSION_USB2 == major_ver) + { + FUSB_INFO("For USB2, default full speed, low speed and high speed bit rate supported !!!"); + } + } - break; - case FXHCI_EXT_CAP_ID_USB_DEBUG_CAPABILITY: + break; + case FXHCI_EXT_CAP_ID_USB_DEBUG_CAPABILITY: - break; - default: - FUSB_WARN("Unhandled extend capabilities %d", cap_id); - break; + break; + default: + FUSB_WARN("Unhandled extend capabilities %d", cap_id); + break; } return; @@ -181,7 +185,7 @@ void FXhciListExtCap(FXhciMMIO *mmio) cap_id = FXHCI_REG_EXT_CAP_CAP_ID_GET(reg_val); FXhciParseExtCap(mmio, ext_cap_offset, cap_id); - FUSB_INFO("==== Capability ID: %d, Next Capability Pointer: 0x%x", + FUSB_INFO("Capability ID: %d, Next Capability Pointer: 0x%x", cap_id, next_ext_cap_offset); ext_cap_offset += next_ext_cap_offset; } @@ -210,7 +214,7 @@ FError FXhciWaitOper32(FXhciMMIO *mmio, u32 offset, u32 mask, u32 exp_val, u32 t if (FUSB_SUCCESS != ret) { - FUSB_ERROR("wait status 0x%x timeout, current 0x%x, tick: %ld", exp_val, mask, tick); + FUSB_ERROR("Waitting status 0x%x timeout, current 0x%x, tick: %ld", exp_val, mask, tick); } return ret; diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.h b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.h index 6c780e6a96..c3e3605014 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_hw.h @@ -19,22 +19,21 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_USB_FXHCI_HW_H -#define DRIVERS_USB_FXHCI_HW_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FXHCI_HW_H +#define FXHCI_HW_H /***************************** Include Files *********************************/ #include "fio.h" #include "fassert.h" #include "fkernel.h" +#ifdef __cplusplus +extern "C" +{ +#endif /************************** Constant Definitions *****************************/ /** @name Register Map @@ -244,8 +243,8 @@ enum #define FXHCI_REG_OP_PORTS_PORTSC_DR (1 << 30) /* Device Removable, 0: Device is removable. 1: Device is non-removable */ #define FXHCI_REG_OP_PORTS_PORTSC_WPR (1 << 31) /* Warm Port Reset 1: follow Warm Reset sequence */ #define FXHCI_REG_OP_PORTS_PORTSC_RW_MASK (FXHCI_REG_OP_PORTS_PORTSC_PR | FXHCI_REG_OP_PORTS_PORTSC_PLS_MASK | FXHCI_REG_OP_PORTS_PORTSC_PP \ - | FXHCI_REG_OP_PORTS_PORTSC_PIC_MASK | FXHCI_REG_OP_PORTS_PORTSC_LWS | FXHCI_REG_OP_PORTS_PORTSC_WCE \ - | FXHCI_REG_OP_PORTS_PORTSC_WDE | FXHCI_REG_OP_PORTS_PORTSC_WOE) + | FXHCI_REG_OP_PORTS_PORTSC_PIC_MASK | FXHCI_REG_OP_PORTS_PORTSC_LWS | FXHCI_REG_OP_PORTS_PORTSC_WCE \ + | FXHCI_REG_OP_PORTS_PORTSC_WDE | FXHCI_REG_OP_PORTS_PORTSC_WOE) /***************** Host Controller Runtime Registers ***********************/ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_private.h b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_private.h index 818b5f2520..e181a7b999 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_private.h +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_private.h @@ -19,22 +19,22 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ -#ifndef DRIVERS_USB_FXHCI_PRIVATE_H -#define DRIVERS_USB_FXHCI_PRIVATE_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FXHCI_PRIVATE_H +#define FXHCI_PRIVATE_H /***************************** Include Files *********************************/ #include "fusb_private.h" #include "fxhci_hw.h" #include "fxhci.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /************************** Constant Definitions *****************************/ typedef enum { @@ -284,10 +284,10 @@ typedef struct #define FXHCI_TRB_ID_LEN 8 #define FXHCI_TRB_MASK(tok) FXHCI_MASK(FXHCI_TRB_##tok##_START, FXHCI_TRB_##tok##_LEN) #define FXHCI_TRB_GET(tok, trb) (((trb)->FXHCI_TRB_##tok##_FIELD & FXHCI_TRB_MASK(tok)) \ - >> FXHCI_TRB_##tok##_START) + >> FXHCI_TRB_##tok##_START) #define FXHCI_TRB_SET(tok, trb, to) (trb)->FXHCI_TRB_##tok##_FIELD = \ - (((trb)->FXHCI_TRB_##tok##_FIELD & ~FXHCI_TRB_MASK(tok)) | \ - (((to) << FXHCI_TRB_##tok##_START) & FXHCI_TRB_MASK(tok))) + (((trb)->FXHCI_TRB_##tok##_FIELD & ~FXHCI_TRB_MASK(tok)) | \ + (((to) << FXHCI_TRB_##tok##_START) & FXHCI_TRB_MASK(tok))) #define FXHCI_TRB_DUMP(dumper, tok, trb) dumper(" "#tok"\t0x%04x ", FXHCI_TRB_GET(tok, trb)) #define FXHCI_TRB_CYCLE (1 << 0) @@ -331,10 +331,10 @@ typedef struct #define FXHCI_SC_STATE_LEN 5 #define FXHCI_SC_MASK(tok) FXHCI_MASK(FXHCI_SC_##tok##_START, FXHCI_SC_##tok##_LEN) #define FXHCI_SC_GET(tok, sc) (((sc)->FXHCI_SC_##tok##_FIELD & FXHCI_SC_MASK(tok)) \ - >> FXHCI_SC_##tok##_START) + >> FXHCI_SC_##tok##_START) #define FXHCI_SC_SET(tok, sc, to) (sc)->FXHCI_SC_##tok##_FIELD = \ - (((sc)->FXHCI_SC_##tok##_FIELD & ~FXHCI_SC_MASK(tok)) | \ - (((to) << FXHCI_SC_##tok##_START) & FXHCI_SC_MASK(tok))) + (((sc)->FXHCI_SC_##tok##_FIELD & ~FXHCI_SC_MASK(tok)) | \ + (((to) << FXHCI_SC_##tok##_START) & FXHCI_SC_MASK(tok))) #define FXHCI_SC_DUMP(dumper, tok, sc) dumper(" "#tok"\t0x%04x ", FXHCI_SC_GET(tok, sc)) /* shortcut to access endpoint context */ @@ -374,10 +374,10 @@ typedef struct #define FXHCI_EC_MASK(tok) FXHCI_MASK(FXHCI_EC_##tok##_START, FXHCI_EC_##tok##_LEN) #define FXHCI_EC_GET(tok, ec) (((ec)->FXHCI_EC_##tok##_FIELD & FXHCI_EC_MASK(tok)) \ - >> FXHCI_EC_##tok##_START) + >> FXHCI_EC_##tok##_START) #define FXHCI_EC_SET(tok, ec, to) (ec)->FXHCI_EC_##tok##_FIELD = \ - (((ec)->FXHCI_EC_##tok##_FIELD & ~FXHCI_EC_MASK(tok)) | \ - (((to) << FXHCI_EC_##tok##_START) & FXHCI_EC_MASK(tok))) + (((ec)->FXHCI_EC_##tok##_FIELD & ~FXHCI_EC_MASK(tok)) | \ + (((to) << FXHCI_EC_##tok##_START) & FXHCI_EC_MASK(tok))) #define FXHCI_EC_DUMP(dumper, tok, ec) dumper(" "#tok"\t0x%04x ", FXHCI_EC_GET(tok, ec)) /* the current operational state of the endpoint. */ diff --git a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_roothub.c b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_roothub.c index 56619be498..83b545be0a 100644 --- a/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_roothub.c +++ b/bsp/phytium/libraries/standalone/drivers/usb/fxhci/fxhci_roothub.c @@ -19,7 +19,7 @@ * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 Zhugengyu 2022/2/7 init commit + * 1.0 zhugengyu 2022/2/7 init commit */ #include "fdebug.h" @@ -122,7 +122,7 @@ static int FXhciRootHubResetPort(FUsbDev *const dev, const int port) if (FUsbGenericHubWaitForPort(dev, port, 0, FXhciRootHubPortInReset, 150, 1000) == 0) { - FUSB_INFO("xhci_rh: Reset timed out at port %d ", port); + FUSB_INFO("Xhci root hub: Reset timed out at port %d ", port); } else { @@ -189,5 +189,5 @@ void FXhciRootHubInit(FUsbDev *dev) FUsbGenericHubInit(dev, num_ports, &FXHCI_ROOTHUB_OPS); - FUSB_INFO("xHCI: root hub init done "); + FUSB_INFO("Xhci: root hub init done. "); } diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/Kconfig b/bsp/phytium/libraries/standalone/drivers/watchdog/Kconfig index 5d2860d27b..5da173ab68 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/Kconfig +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/Kconfig @@ -4,7 +4,7 @@ menu "FWDT Configuration" bool prompt "Use FWDT" default n - + endmenu diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.c b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.c index 68b0db3f15..0fc9c907fd 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.c +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.c @@ -13,7 +13,7 @@ * FilePath: fwdt.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-07-15 17:05:09 - * Description:  This files is for wdt ctrl function implementation. + * Description:  This file is for wdt ctrl function implementation. * Users can operate as a single stage watchdog or a two stages watchdog. * In the single stage mode, when the timeout is reached, your system will * be reset by WS1. The first signal (WS0) is ignored. @@ -56,7 +56,7 @@ #include "fwdt.h" #include "fwdt_hw.h" -#define FWDT_DEBUG_TAG "WDT" +#define FWDT_DEBUG_TAG "FWDT" #define FWDT_ERROR(format, ...) FT_DEBUG_PRINT_E(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) #define FWDT_WARN(format, ...) FT_DEBUG_PRINT_W(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) #define FWDT_INFO(format, ...) FT_DEBUG_PRINT_I(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) @@ -82,7 +82,7 @@ FError FWdtCfgInitialize(FWdtCtrl *pctrl, const FWdtConfig *input_config_p) */ if (FT_COMPONENT_IS_READY == pctrl->is_ready) { - FWDT_WARN("device is already initialized!!!"); + FWDT_WARN("Device is already initialized!!!"); } /*Set default values and configuration data */ @@ -126,17 +126,17 @@ FError FWdtSetTimeout(FWdtCtrl *pctrl, u32 timeout) FASSERT(pctrl != NULL); if (pctrl->is_ready != FT_COMPONENT_IS_READY) { - FWDT_ERROR("device is not already!!!"); + FWDT_ERROR("Device is not ready!!!"); return FWDT_NOT_READY; } if (timeout > FWDT_MAX_TIMEOUT) { - FWDT_ERROR("timeout value is invalid"); + FWDT_ERROR("Timeout value is invalid."); return FWDT_ERR_INVAL_PARM; } uintptr base_addr = pctrl->config.control_base_addr; - FWDT_WRITE_REG32(base_addr, FWDT_GWDT_WOR, (u32)(FWDT_CLK * timeout)); + FWDT_WRITE_REG32(base_addr, FWDT_GWDT_WOR, (u32)(FWDT_CLK_FREQ_HZ * timeout)); return FWDT_SUCCESS; } @@ -156,7 +156,9 @@ u32 FWdtGetTimeleft(FWdtCtrl *pctrl) /* if the ws0 bit of register WCS is zero,indicates that there is one more timeout opportunity */ if (!(FWdtReadWCS(base_addr) & FWDT_GWDT_WCS_WS0)) + { timeleft += FWdtReadWOR(base_addr); + } u32 wcvh = (u32)FWdtReadWCVH(base_addr); u32 wcvl = (u32)FWdtReadWCVL(base_addr); @@ -164,9 +166,9 @@ u32 FWdtGetTimeleft(FWdtCtrl *pctrl) timeleft += (wcv - GenericTimerRead()); - // f_printk("------wcvh=%llx, wcvl=%llx, wcv=%llx, timeleft=%llx\n", wcvh, wcvl, wcv, timeleft); + FWDT_DEBUG("wcvh=%llx, wcvl=%llx, wcv=%llx, timeleft=%llx\n", wcvh, wcvl, wcv, timeleft); - do_div(timeleft, FWDT_CLK); + do_div(timeleft, FWDT_CLK_FREQ_HZ); return (u32)timeleft; } @@ -182,7 +184,7 @@ FError FWdtRefresh(FWdtCtrl *pctrl) FASSERT(pctrl != NULL); if (pctrl->is_ready != FT_COMPONENT_IS_READY) { - FWDT_ERROR("device is not already!!!"); + FWDT_ERROR("Device is not ready!!!"); return FWDT_NOT_READY; } uintptr base_addr = pctrl->config.refresh_base_addr; @@ -201,7 +203,7 @@ FError FWdtStart(FWdtCtrl *pctrl) FASSERT(pctrl != NULL); if (pctrl->is_ready != FT_COMPONENT_IS_READY) { - FWDT_ERROR("device is not already!!!"); + FWDT_ERROR("Device is not ready!!!"); return FWDT_NOT_READY; } @@ -239,13 +241,13 @@ FError FWdtReadFWdtReadWIIDR(FWdtCtrl *pctrl, FWdtIdentifier *wdt_identify) if (pctrl->is_ready != FT_COMPONENT_IS_READY) { - FWDT_ERROR("device is not already!!!"); + FWDT_ERROR("Device is not ready!!!"); return FWDT_NOT_READY; } u32 reg_val = 0; uintptr base_addr = pctrl->config.refresh_base_addr; - reg_val = FWDT_READ_REG32(base_addr, FWDT_GWDT_W_IIDR); + reg_val = FWDT_READ_REG32(base_addr, FWDT_GWDT_W_IIR); wdt_identify->version = (u16)((reg_val & FWDT_VERSION_MASK) >> 16); wdt_identify->continuation_code = (u8)((reg_val & FWDT_CONTINUATION_CODE_MASK) >> 8); diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.h b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.h index e1fcc10390..3710f1051b 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.h +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt.h @@ -14,7 +14,7 @@ * FilePath: fwdt.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:24:34 - * Description:  This files is for wdt ctrl function definition + * Description:  This file is for wdt ctrl function definition. * * Modify History: * Ver   Who        Date         Changes @@ -23,13 +23,8 @@ * 1.1 Wangxiaodong 2021/11/5 restruct */ -#ifndef BSP_DRIVERS_FWDT_H -#define BSP_DRIVERS_FWDT_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FWDT_H +#define FWDT_H #include "ftypes.h" #include "fdebug.h" @@ -37,6 +32,11 @@ extern "C" #include "fkernel.h" #include "fassert.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define FWDT_SUCCESS FT_SUCCESS #define FWDT_ERR_INVAL_PARM FT_MAKE_ERRCODE(ErrModBsp, ErrBspWdt, 1) #define FWDT_NOT_READY FT_MAKE_ERRCODE(ErrModBsp, ErrBspWdt, 2) @@ -58,8 +58,10 @@ typedef struct u32 instance_id;/* wdt id */ uintptr refresh_base_addr;/* wdt refresh base addr */ uintptr control_base_addr;/* wdt control base addr */ - u32 irq_num; /* wdt ir num */ + u32 irq_num; /* wdt irq num */ u32 irq_prority;/* wdt irq priority */ + u32 irq_twice_num; /* wdt twice irq num */ + u32 irq_twice_prority;/* wdt twice irq priority */ const char *instance_name;/* instance name */ } FWdtConfig; /* wdt config */ diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_g.c b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_g.c index 21bc05458b..b1a16e0caf 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_g.c +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_g.c @@ -13,36 +13,115 @@ * * FilePath: fwdt_g.c * Date: 2022-02-10 14:53:42 - * LastEditTime: 2022-02-18 09:22:49 - * Description:  This files is for static config of wdt ctrl + * LastEditTime: 2022-06-18 09:22:49 + * Description:  This file is for static config of wdt device. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 Wangxiaodong 2021/8/25 init + * 1.1 Wangxiaodong 2022/6/25 adapt to e2000 */ #include "fparameters.h" #include "fwdt.h" /* default configs of wdt ctrl */ -const FWdtConfig FWdtConfigTbl[FWDT_INSTANCE_NUM] = +const FWdtConfig FWdtConfigTbl[FWDT_NUM] = { + [FWDT0_ID] = { - .instance_id = FWDT_INSTANCE_0, - .refresh_base_addr = FWDT0_REFRESH_BASE, - .control_base_addr = FWDT0_CONTROL_BASE, - .irq_num = FWDT0_INTR_IRQ, + .instance_id = FWDT0_ID, + .refresh_base_addr = FWDT0_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT0_REFRESH_BASE_ADDR), + .irq_num = FWDT0_IRQ_NUM, .irq_prority = 0, + #if defined(TARDIGRADE) + .irq_twice_num = FWDT0_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + #endif .instance_name = "WDT-0" }, - + [FWDT1_ID] = { - .instance_id = FWDT_INSTANCE_1, - .refresh_base_addr = FWDT1_REFRESH_BASE, - .control_base_addr = FWDT1_CONTROL_BASE, - .irq_num = FWDT1_INTR_IRQ, + .instance_id = FWDT1_ID, + .refresh_base_addr = FWDT1_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT1_REFRESH_BASE_ADDR), + .irq_num = FWDT1_IRQ_NUM, .irq_prority = 0, + #if defined(TARDIGRADE) + .irq_twice_num = FWDT1_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + #endif .instance_name = "WDT-1" - } + }, + + #if defined(TARDIGRADE) + [FWDT2_ID] = + { + .instance_id = FWDT2_ID, + .refresh_base_addr = FWDT2_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT2_REFRESH_BASE_ADDR), + .irq_num = FWDT2_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT2_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-2" + }, + [FWDT3_ID] = + { + .instance_id = FWDT3_ID, + .refresh_base_addr = FWDT3_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT3_REFRESH_BASE_ADDR), + .irq_num = FWDT3_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT3_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-3" + }, + [FWDT4_ID] = + { + .instance_id = FWDT4_ID, + .refresh_base_addr = FWDT4_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT4_REFRESH_BASE_ADDR), + .irq_num = FWDT4_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT4_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-4" + }, + [FWDT5_ID] = + { + .instance_id = FWDT5_ID, + .refresh_base_addr = FWDT5_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT5_REFRESH_BASE_ADDR), + .irq_num = FWDT5_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT5_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-5" + }, + [FWDT6_ID] = + { + .instance_id = FWDT6_ID, + .refresh_base_addr = FWDT6_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT6_REFRESH_BASE_ADDR), + .irq_num = FWDT6_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT6_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-6" + }, + [FWDT7_ID] = + { + .instance_id = FWDT7_ID, + .refresh_base_addr = FWDT7_REFRESH_BASE_ADDR, + .control_base_addr = FWDT_CONTROL_BASE_ADDR(FWDT7_REFRESH_BASE_ADDR), + .irq_num = FWDT7_IRQ_NUM, + .irq_prority = 0, + .irq_twice_num = FWDT7_TWICE_IRQ_NUM, + .irq_twice_prority = 0, + .instance_name = "WDT-7" + }, + #endif // TARDIGRADE }; diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.c b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.c index d81b945332..d31383ef8c 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.c +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.c @@ -14,16 +14,19 @@ * FilePath: fwdt_hw.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 09:23:08 - * Description:  This files is for wdt register function + * Description:  This file is for wdt register implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/15 init commit */ /***************************** Include Files *********************************/ - +#include +#include "fparameters.h" #include "fwdt_hw.h" +#include "fdebug.h" /************************** Constant Definitions *****************************/ @@ -35,3 +38,30 @@ /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ + +#define FWDT_DEBUG_TAG "FWDT_HW" +#define FWDT_ERROR(format, ...) FT_DEBUG_PRINT_E(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_WARN(format, ...) FT_DEBUG_PRINT_W(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_INFO(format, ...) FT_DEBUG_PRINT_I(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_DEBUG(format, ...) FT_DEBUG_PRINT_D(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) + +/** + * @name: FWdtDump + * @msg: debug register value for wdt. + * @param {uintptr} base_addr, base address of FWDT controller + * @return {*} + */ +void FWdtDump(uintptr base_addr) +{ + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_WRR, FWDT_READ_REG32(base_addr, FWDT_GWDT_WRR)); + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_W_IIR, FWDT_READ_REG32(base_addr, FWDT_GWDT_W_IIR)); + + base_addr = FWDT_CONTROL_BASE_ADDR(base_addr); + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_WCS, FWDT_READ_REG32(base_addr, FWDT_GWDT_WCS)); + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_WOR, FWDT_READ_REG32(base_addr, FWDT_GWDT_WOR)); + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_WCVL, FWDT_READ_REG32(base_addr, FWDT_GWDT_WCVL)); + FWDT_DEBUG("Off[0x%x]: = 0x%08x\r\n", base_addr + FWDT_GWDT_WCVH, FWDT_READ_REG32(base_addr, FWDT_GWDT_WCVH)); + + FWDT_DEBUG("\r\n"); + +} diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.h b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.h index ede7d81373..f1d7ab9821 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.h +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_hw.h @@ -14,29 +14,30 @@ * FilePath: fwdt_hw.h * Date: 2021-08-25 10:27:42 * LastEditTime: 2022-02-25 11:44:33 - * Description:  This files is for ctrl of watchdog timer functions + * Description:  This file is for wdt register definition. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- - * 1.0 wangxiaodong 2021/8/25 init + * 1.0 wangxiaodong 2022/4/15 init commit */ -#ifndef BSP_DRIVERS_FWDT_HW_H -#define BSP_DRIVERS_FWDT_HW_H +#ifndef FWDT_HW_H +#define FWDT_HW_H + +#include "fkernel.h" +#include "fio.h" #ifdef __cplusplus extern "C" { #endif -#include "fkernel.h" -#include "fio.h" - /* Watchdog register definitions */ /* refresh frame */ #define FWDT_GWDT_WRR 0x000 +#define FWDT_GWDT_W_IIR 0xfcc /* control frame */ #define FWDT_GWDT_WCS 0x000 /* WCS register */ @@ -44,10 +45,6 @@ extern "C" #define FWDT_GWDT_WCVL 0x010 #define FWDT_GWDT_WCVH 0x014 -/* refresh/control frame */ -#define FWDT_GWDT_W_IIDR 0xfcc -#define FWDT_GWDT_IDR 0xfd0 - /* Watchdog Control and Status Register */ #define FWDT_GWDT_WCS_WDT_EN BIT(0) #define FWDT_GWDT_WCS_WS0 BIT(1) @@ -124,6 +121,8 @@ static inline u32 FWdtReadWCS(uintptr addr) return FWDT_READ_REG32(addr, FWDT_GWDT_WCS); } +void FWdtDump(uintptr base_addr); + #ifdef __cplusplus } #endif diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_intr.c b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_intr.c index 39972e27a0..b10a4cde2c 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_intr.c +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_intr.c @@ -14,9 +14,10 @@ * FilePath: fwdt_intr.c * Date: 2021-11-05 10:01:59 * LastEditTime: 2022-02-25 11:44:02 - * Description:  This files is for intrrupt function of wdt ctrl + * Description:  This file is for wdt interrupt handler implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ diff --git a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_sinit.c b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_sinit.c index 69498558e4..89250d8438 100644 --- a/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_sinit.c +++ b/bsp/phytium/libraries/standalone/drivers/watchdog/fwdt/fwdt_sinit.c @@ -14,11 +14,12 @@ * FilePath: fwdt_sinit.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-25 11:45:05 - * Description:  This files is for + * Description:  This file is for wdt static variables implementation. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/4/25 init commit */ @@ -34,7 +35,7 @@ #define FWDT_DEBUG(format, ...) FT_DEBUG_PRINT_D(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) -extern FWdtConfig FWdtConfigTbl[FWDT_INSTANCE_NUM]; +extern FWdtConfig FWdtConfigTbl[FWDT_NUM]; /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -56,13 +57,13 @@ const FWdtConfig *FWdtLookupConfig(u32 instance_id) const FWdtConfig *pconfig = NULL; u32 index; - if (instance_id >= FWDT_INSTANCE_NUM) + if (instance_id >= FWDT_NUM) { FWDT_ERROR("wdt id is not invalid."); return NULL; } - for (index = 0; index < (u32)FWDT_INSTANCE_NUM; index++) + for (index = 0; index < (u32)FWDT_NUM; index++) { if (FWdtConfigTbl[index].instance_id == instance_id) { diff --git a/bsp/phytium/libraries/standalone/gitinfo b/bsp/phytium/libraries/standalone/gitinfo index 4cb410e5a6..e6334ebcef 100644 --- a/bsp/phytium/libraries/standalone/gitinfo +++ b/bsp/phytium/libraries/standalone/gitinfo @@ -1,4 +1,3 @@ -[commit-id]: -ccf728ed578713cae89a5472f7dfb6fbd01e7a70 -[branch]: -new_master +[commit-id]: 41da10704f28d248120e389ae889e92f43f49a98 +[branch]: pin_example_reconsitution +[date]: 2023-03-09 14:58:04 diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcache.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcache.c new file mode 100644 index 0000000000..ed999cdfc7 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcache.c @@ -0,0 +1,56 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fcache.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for aarch32 cache functions port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include +#include "fassert.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ +extern void rt_hw_cpu_dcache_invalidate(void *addr, int size); +extern void rt_hw_cpu_dcache_clean(void *addr, int size); + +/************************** Function *****************************************/ +void FCacheDCacheInvalidate(void) +{ + /* there is no dcache invalidate implmentation for contrex-a aarch32, use flush instead */ + rt_cpu_dcache_clean_flush(); +} + +void FCacheDCacheInvalidateRange(intptr adr, intptr len) +{ + rt_hw_cpu_dcache_invalidate((void *)adr, (int)len); +} + +void FCacheDCacheFlushRange(intptr adr, intptr len) +{ + rt_hw_cpu_dcache_clean((void *)adr, (int)len); +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.c new file mode 100644 index 0000000000..e2945ede4b --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.c @@ -0,0 +1,39 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fcp15.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for cp15 function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include "fassert.h" +#include "fcp15.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.h new file mode 100644 index 0000000000..b2221399ab --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fcp15.h @@ -0,0 +1,59 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fcp15.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for cp15 function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ +#ifndef FDRV_AARCH32_H +#define FDRV_AARCH32_H + +/***************************** Include Files *********************************/ +#include +#include "ftypes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +static inline void WMB(void) +{ + __asm__ __volatile__("dsb" \ + : \ + : \ + : "memory"); +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fgeneric_timer.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fgeneric_timer.c new file mode 100644 index 0000000000..8512d86856 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fgeneric_timer.c @@ -0,0 +1,93 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fgeneric_timer.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for generic timer function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include + +#include "fkernel.h" +#include "fassert.h" +#include "fgeneric_timer.h" + +/************************** Constant Definitions *****************************/ +#define CNTP_CTL_ENABLE (1U << 0) /* Enables the timer */ +#define CNTP_CTL_IMASK (1U << 1) /* Timer interrupt mask bit */ +#define CNTP_CTL_ISTATUS (1U << 2) /* The status of the timer */ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +u64 GenericTimerRead(void) +{ + return (u64)gtimer_get_current_value(); +} + +void GenericTimerStart(void) +{ + u32 ctrl = gtimer_get_control(); /* get CNTP_CTL */ + + if (!(ctrl & CNTP_CTL_ENABLE)) + { + ctrl |= CNTP_CTL_ENABLE; /* enable gtimer if off */ + gtimer_set_control(ctrl); /* set CNTP_CTL */ + } +} + +void GenericTimerStop(void) +{ + u32 ctrl = gtimer_get_control(); /* get CNTP_CTL */ + if ((ctrl & CNTP_CTL_ENABLE)) + { + ctrl &= ~CNTP_CTL_ENABLE; /* disable gtimer if on */ + gtimer_set_control(ctrl); /* set CNTP_CTL */ + } +} + +u32 GenericTimerFrequecy(void) +{ + u32 rate = gtimer_get_counter_frequency(); /* get CNTFRQ bit[31:0] freq of system counter */ + FASSERT_MSG((rate > 1000000), "invalid freqency %ud", rate); + return rate; +} + +void GenericTimerCompare(u32 interval) +{ + /* set CNTP_CVAL, set compare value for physical timer */ + gtimer_set_load_value((rt_uint64_t)interval); +} + +void GenericTimerInterruptEnable(void) +{ + u64 ctrl = gtimer_get_control(); + if (ctrl & CNTP_CTL_IMASK) + { + ctrl &= ~CNTP_CTL_IMASK; + gtimer_set_control(ctrl); + } +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.c similarity index 93% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.c rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.c index 2c2e298b23..19dc830d38 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.c +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.c @@ -11,14 +11,15 @@ * See the Phytium Public License for more details. * * - * FilePath: psci.c + * FilePath: fpsci.c * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:30:35 - * Description:  This files is for + * Description:  This file is for cpu energy management * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release */ diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.h similarity index 86% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.h rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.h index d79f0ba548..195a787ffd 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fpsci.h +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fpsci.h @@ -14,16 +14,17 @@ * FilePath: fpsci.h * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:30:40 - * Description:  This files is for + * Description:  This file is for cpu energy management * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release */ -#ifndef BSP_ARCH_ARMV8_AARCH32_PSCI_H -#define BSP_ARCH_ARMV8_AARCH32_PSCI_H +#ifndef ARCH_ARMV8_AARCH32_PSCI_H +#define ARCH_ARMV8_AARCH32_PSCI_H #ifdef __cplusplus extern "C" diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsleep.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsleep.c new file mode 100644 index 0000000000..165b599c52 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsleep.c @@ -0,0 +1,53 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fsleep.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for sleep function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include "fassert.h" +#include "fsleep.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +u32 fsleep_seconds(u32 seconds) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} + +u32 fsleep_millisec(u32 mseconds) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} + +u32 fsleep_microsec(u32 useconds) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmc.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmc.h new file mode 100644 index 0000000000..445ba4813c --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmc.h @@ -0,0 +1,76 @@ +/* + * @Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * @FilePath: fsmc.h + * @Date: 2023-04-19 10:14:11 + * @LastEditTime: 2023-04-19 10:14:12 + * @Description: This file is for + * + * @Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + */ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fsmc.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:30:49 + * Description:  This file is for Non-secure SMC Call + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release + */ + + +#ifndef ARCH_ARMV8_AARCH32_SMC_H +#define ARCH_ARMV8_AARCH32_SMC_H + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "ftypes.h" + +typedef struct +{ + /* data */ + u32 function_identifier; + u32 a1; + u32 a2; + u32 a3; + u32 a4; + u32 a5; + u32 a6; + +} FSmc_Data_t; + +void FSmcCall(FSmc_Data_t *Input, FSmc_Data_t *Output); + +#ifdef __cplusplus +} +#endif + +#endif // !FT_SMC_H diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/gcc/fsmccc_call.S b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmccc_call.S similarity index 95% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch32/gcc/fsmccc_call.S rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmccc_call.S index 16b14b209e..7845646194 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/gcc/fsmccc_call.S +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/fsmccc_call.S @@ -14,11 +14,12 @@ * FilePath: smccc-call.S * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:28:10 - * Description:  This files is for + * Description:  This file is for initiating SMC call * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release */ diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/sdkopts.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/sdkopts.h new file mode 100644 index 0000000000..3379577aa6 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch32/sdkopts.h @@ -0,0 +1,61 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: sdkopts.h + * Date: 2022-09-16 13:54:28 + * LastEditTime: 2022-09-16 13:54:28 + * Description: This file is for configure sdkconfig in non-Kconfig way + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liuzhihong 2022/10/20 first release + */ + +#ifndef SDK_OPTS_H +#define SDK_OPTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*******************Control Options*******************/ +/* cpu aarch 32/64 */ +#define CPU_AARCH 32 +#define TARGET_NAME "e2000d_baremetal_a32" + +/* e2000d e2000q e2000s d2000 ft2004 */ +#define CPU_TYPE_E2000D 0 +#define CPU_TYPE_E2000Q 1 +#define CPU_TYPE_E2000S 2 +#define CPU_TYPE_D2000 3 +#define CPU_TYPE_FT2004 4 +#define CPU_TYPE CPU_TYPE_E2000D + +/* log type */ +#define LOG_TYPE_VERBOS 0 +#define LOG_TYPE_DEBUG 1 +#define LOG_TYPE_INFO 2 +#define LOG_TYPE_WARN 3 +#define LOG_TYPE_ERROR 4 +#define LOG_TYPE_NONE 5 +#define LOG_TYPE LOG_TYPE_ERROR + +/*******************SDK Configures*******************/ +#include "sdkopts.h" + +#ifdef __cplusplus +} +#endif + +#endif /* SDK_OPTS_H */ \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.c new file mode 100644 index 0000000000..88906b1e2d --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.c @@ -0,0 +1,39 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: faarch64.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for aarch64 function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include "fassert.h" +#include "faarch64.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.h new file mode 100644 index 0000000000..9c0c9ee4fe --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/faarch64.h @@ -0,0 +1,53 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: faarch64.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for aarch64 function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ +#ifndef FDRV_AARCH64_H +#define FDRV_AARCH64_H + +/***************************** Include Files *********************************/ +#include +#include "ftypes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +void WMB(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/farm_smccc.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/farm_smccc.h similarity index 93% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch64/farm_smccc.h rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/farm_smccc.h index c682d38533..670d4bf993 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/farm_smccc.h +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/farm_smccc.h @@ -14,15 +14,23 @@ * FilePath: farm_smccc.h * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:32:15 - * Description:  This files is for + * Description:  This file is for initiating SMC call * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/6/13 first release */ -#ifndef __LINUX_ARM_SMCCC_H -#define __LINUX_ARM_SMCCC_H +#ifndef FARM_SMCCC_H +#define FARM_SMCCC_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* * This file provides common defines for ARM SMC Calling Convention as @@ -72,7 +80,6 @@ #ifndef __ASSEMBLY__ -#include /** * struct arm_smccc_res - Result from SMC/HVC call * @a0-a3 result values from registers 0 to 3 @@ -117,9 +124,14 @@ void __arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a5, unsigned long a6, unsigned long a7, struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); -#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) +#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__) #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) #endif /*__ASSEMBLY__*/ + +#ifdef __cplusplus +} +#endif + #endif /*__LINUX_ARM_SMCCC_H*/ \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fcache.c_x b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fcache.c_x new file mode 100644 index 0000000000..cfda8c9404 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fcache.c_x @@ -0,0 +1,52 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fcache.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for aarch64 cache function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include "fassert.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +void FCacheDCacheInvalidate(void) +{ + rt_hw_dcache_invalidate_all(); +} + +void FCacheDCacheInvalidateRange(intptr adr, intptr len) +{ + rt_hw_dcache_invalidate_range((unsigned long)adr, (unsigned long)len); +} + +void FCacheDCacheFlushRange(intptr adr, intptr len) +{ + rt_hw_dcache_flush_range((unsigned long)adr, (unsigned long)len); +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fgeneric_timer.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fgeneric_timer.c new file mode 100644 index 0000000000..ead65027be --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fgeneric_timer.c @@ -0,0 +1,112 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fgeneric_timer.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for generic timer function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include "fassert.h" +#include "fgeneric_timer.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fgeneric_timer.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for generic timer function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include + +#include "fassert.h" +#include "fgeneric_timer.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +u64 GenericTimerRead(void) +{ + return (u64)rt_hw_get_gtimer_val(); +} + +void GenericTimerStart(void) +{ + /* shall not be called in rtt */ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} + +void GenericTimerStop(void) +{ + /* shall not be called in rtt */ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} + +u32 GenericTimerFrequecy(void) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); + return 0U; +} + +void GenericTimerCompare(u32 interval) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} + +void GenericTimerInterruptEnable(void) +{ + FASSERT_MSG(0, "%s not implment !!!", __func__); +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.c similarity index 75% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.c rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.c index fb5f8ec686..36b373683b 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/fpsci.c +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.c @@ -11,14 +11,15 @@ * See the Phytium Public License for more details. * * - * FilePath: psci.c + * FilePath: fpsci.c * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:33:51 - * Description:  This files is for + * Description:  This file is for cpu energy management * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release */ #include "fpsci.h" @@ -26,22 +27,25 @@ #include "ftypes.h" #include "fcpu_info.h" #include "ferror_code.h" +#include "fprintk.h" FError PsciCpuOn(s32 cpu_id_mask, uintptr bootaddr) { FError ret ; u64 cluster = 0; + struct arm_smccc_res res; + struct arm_smccc_quirk quirk; ret = GetCpuAffinityByMask(cpu_id_mask, &cluster); if (ret != ERR_SUCCESS) { - printf("GetCpuAffinity is failed \r\n") ; + f_printk("GetCpuAffinity is failed \r\n") ; return ret ; } - arm_smccc_smc(0xc4000003, cluster, bootaddr, 0, 0, 0, 0, 0, 0); + __arm_smccc_smc(0xc4000003, cluster, bootaddr, 0, 0, 0, 0, 0,&res, &quirk); return ERR_SUCCESS ; } void PsciCpuReset(void) { struct arm_smccc_res res; - arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res); + __arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res,NULL); } \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.h new file mode 100644 index 0000000000..c672a45bbd --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fpsci.h @@ -0,0 +1,66 @@ +/* + * @Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * @FilePath: fpsci.h + * @Date: 2023-04-21 15:39:57 + * @LastEditTime: 2023-04-21 15:39:57 + * @Description: This file is for + * + * @Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + */ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fpsci.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:34:06 + * Description:  This file is for cpu energy management + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release + */ + + +#ifndef FPSCI_H +#define FPSCI_H + +#include "ftypes.h" +#include "ferror_code.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +void PsciCpuReset(void); +FError PsciCpuOn(s32 cpu_id_mask, uintptr bootaddr); + +#ifdef __cplusplus +} +#endif + +#endif // FPSCI_H \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsleep.c b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsleep.c new file mode 100644 index 0000000000..d6ce7e0071 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsleep.c @@ -0,0 +1,71 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fsleep.c + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for sleep function port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ + +/***************************** Include Files *********************************/ +#include + +#include "fassert.h" +#include "fsleep.h" +#include "fkernel.h" +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +static u32 fsleep_general(u32 ticks, u32 div) +{ + u64 end_time; + u64 cur_time; + cur_time = rt_hw_get_gtimer_val(); + end_time = cur_time + ((u64)ticks * rt_hw_get_gtimer_frq() / div); + + do + { + cur_time = rt_hw_get_gtimer_val(); + } + while (cur_time < end_time); + + return 0; +} + +u32 fsleep_seconds(u32 seconds) +{ + return fsleep_general(seconds, 1); +} + +u32 fsleep_millisec(u32 mseconds) +{ + return fsleep_general(mseconds, NANO_TO_MICRO); +} + +u32 fsleep_microsec(u32 useconds) +{ + return fsleep_general(useconds, NANO_TO_KILO); +} \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/gcc/fsmccc_call.S b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsmccc_call.S similarity index 91% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch64/gcc/fsmccc_call.S rename to bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsmccc_call.S index 78464c59bf..27e8e61f26 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch64/gcc/fsmccc_call.S +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/fsmccc_call.S @@ -11,14 +11,15 @@ * See the Phytium Public License for more details. * * - * FilePath: smccc-call.S + * FilePath: fsmccc-call.S * Date: 2022-02-10 14:53:41 * LastEditTime: 2022-02-17 17:31:23 - * Description:  This files is for + * Description:  This file is for initiating SMC call * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2021/7/3 first release */ .macro SMCCC instr diff --git a/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/sdkopts.h b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/sdkopts.h new file mode 100644 index 0000000000..e86224eb82 --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/armv8/aarch64/sdkopts.h @@ -0,0 +1,61 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: sdkopts.h + * Date: 2022-09-16 13:54:28 + * LastEditTime: 2022-09-16 13:54:28 + * Description: This file is for configure sdkconfig in non-Kconfig way + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 zhugengyu 2023/03/03 first release + */ + +#ifndef SDK_OPTS_H +#define SDK_OPTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*******************Control Options*******************/ +/* cpu aarch 32/64 */ +#define CPU_AARCH 64 +#define TARGET_NAME "e2000d_baremetal_a64" + +/* e2000d e2000q e2000s d2000 ft2004 */ +#define CPU_TYPE_E2000D 0 +#define CPU_TYPE_E2000Q 1 +#define CPU_TYPE_E2000S 2 +#define CPU_TYPE_D2000 3 +#define CPU_TYPE_FT2004 4 +#define CPU_TYPE CPU_TYPE_E2000D + +/* log type */ +#define LOG_TYPE_VERBOS 0 +#define LOG_TYPE_DEBUG 1 +#define LOG_TYPE_INFO 2 +#define LOG_TYPE_WARN 3 +#define LOG_TYPE_ERROR 4 +#define LOG_TYPE_NONE 5 +#define LOG_TYPE LOG_TYPE_ERROR + +/*******************SDK Configures*******************/ +#include "sdkopts.h" + +#ifdef __cplusplus +} +#endif + +#endif /* SDK_OPTS_H */ \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/arch/fcache.h b/bsp/phytium/libraries/standalone/port/arch/fcache.h new file mode 100644 index 0000000000..4e1d9d268e --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/arch/fcache.h @@ -0,0 +1,55 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fcache.h + * Date: 2022-02-10 14:53:41 + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for aarch32 cache functions port for driver + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release + */ +#ifndef FDRV_CACHE_AARCH32_H +#define FDRV_CACHE_AARCH32_H + +/***************************** Include Files *********************************/ +#include +#include "ftypes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +void FCacheDCacheInvalidate(void); +void FCacheDCacheInvalidateRange(intptr adr, intptr len); +void FCacheDCacheFlushRange(intptr adr, intptr len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.h b/bsp/phytium/libraries/standalone/port/arch/fgeneric_timer.h similarity index 54% rename from bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.h rename to bsp/phytium/libraries/standalone/port/arch/fgeneric_timer.h index 5a247c3fbd..19e6edefae 100644 --- a/bsp/phytium/libraries/standalone/arch/armv8/aarch32/fgeneric_timer.h +++ b/bsp/phytium/libraries/standalone/port/arch/fgeneric_timer.h @@ -1,5 +1,5 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2023 Phytium Information Technology, Inc. * All Rights Reserved. * * This program is OPEN SOURCE software: you can redistribute it and/or modify it @@ -13,39 +13,46 @@ * * FilePath: fgeneric_timer.h * Date: 2022-02-10 14:53:41 - * LastEditTime: 2022-02-17 17:30:13 - * Description:  This files is for + * LastEditTime: 2022-02-17 17:36:17 + * Description:  This file is for generic timer function port for driver * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release */ +#ifndef FDRV_GENERIC_TIMER_AARCH32_H +#define FDRV_GENERIC_TIMER_AARCH32_H - -#ifndef BSP_ARCH_ARMV8_AARCH32_GENERIC_TIMER_H -#define BSP_ARCH_ARMV8_AARCH32_GENERIC_TIMER_H +/***************************** Include Files *********************************/ +#include +#include "ftypes.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" +/************************** Constant Definitions *****************************/ -typedef void (* GenericTimerTickHandler)(); +/**************************** Type Definitions *******************************/ +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ +u64 GenericTimerRead(void); void GenericTimerStart(void); void GenericTimerStop(void); -void GenericTimerInterruptEnable(void); -void GenericTimerInterruptDisable(void); u32 GenericTimerFrequecy(void); -u64 GenericTimerRead(void); void GenericTimerCompare(u32 interval); -void GenericTimerSetupSystick(u32 tickRateHz, GenericTimerTickHandler tickHandler, u32 intrPrority); -u32 GenericGetTick(void); +void GenericTimerInterruptEnable(void); #ifdef __cplusplus } #endif -#endif // ! \ No newline at end of file +#endif \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/common/fsleep.h b/bsp/phytium/libraries/standalone/port/arch/fsleep.h similarity index 71% rename from bsp/phytium/libraries/standalone/common/fsleep.h rename to bsp/phytium/libraries/standalone/port/arch/fsleep.h index f9d29c201e..b0e78fa80f 100644 --- a/bsp/phytium/libraries/standalone/common/fsleep.h +++ b/bsp/phytium/libraries/standalone/port/arch/fsleep.h @@ -14,21 +14,32 @@ * FilePath: fsleep.h * Date: 2021-05-28 08:48:40 * LastEditTime: 2022-02-17 18:02:51 - * Description:  This files is for + * Description:  This file is for sleep function port for driver * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 zhugengyu 2023/2/28 first release */ -#ifndef _BSP_ARCH_ARMV8_FSLEEP_H -#define _BSP_ARCH_ARMV8_FSLEEP_H +#ifndef FDRV_FSLEEP_H +#define FDRV_FSLEEP_H #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + u32 fsleep_seconds(u32 seconds); /* 按秒延迟 */ u32 fsleep_millisec(u32 mseconds); /* 按毫秒延迟 */ u32 fsleep_microsec(u32 useconds); /* 按微秒延迟 */ +#ifdef __cplusplus +} +#endif + + #endif // ! \ No newline at end of file diff --git a/bsp/phytium/libraries/standalone/port/sdkconfig.h b/bsp/phytium/libraries/standalone/port/sdkconfig.h new file mode 100644 index 0000000000..6be880137e --- /dev/null +++ b/bsp/phytium/libraries/standalone/port/sdkconfig.h @@ -0,0 +1,90 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: sdkopts.h + * Date: 2022-09-16 13:54:28 + * LastEditTime: 2022-09-16 13:54:28 + * Description: This file is for configure sdkconfig in non-Kconfig way + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 zhugengyu 2023/03/01 first release + */ + +#ifndef SDK_CONFIG_H +#define SDK_CONFIG_H + +#include "rtconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(TARGET_ARMV8_AARCH32) +#define CONFIG_TARGET_ARMV8_AARCH32 +#elif defined(TARGET_ARMV8_AARCH64) +#define CONFIG_TARGET_ARMV8_AARCH64 +#endif + +#if defined(TARGET_E2000D) +#define CONFIG_TARGET_E2000 +#define CONFIG_TARGET_E2000D +#elif defined(TARGET_E2000Q) +#define CONFIG_TARGET_E2000 +#define CONFIG_TARGET_E2000Q +#elif defined(TARGET_E2000S) +#define CONFIG_TARGET_E2000 +#define CONFIG_TARGET_E2000S +#elif defined(TARGET_D2000) +#define CONFIG_TARGET_D2000 +#elif defined(TARGET_F2000_4) +#define CONFIG_TARGET_F2000_4 +#endif + +#if defined(LOG_VERBOS) +#define CONFIG_LOG_VERBOS +#elif defined(LOG_DEBUG) +#define CONFIG_LOG_DEBUG +#elif defined(LOG_INFO) +#define CONFIG_LOG_INFO +#elif defined(LOG_WARN) +#define CONFIG_LOG_WARN +#elif defined(LOG_ERROR) +#define CONFIG_LOG_ERROR +#elif defined(LOG_NONE) +#define CONFIG_LOG_NONE +#endif + +#if defined(BSP_USING_UART) +#define CONFIG_USE_SERIAL +#define CONFIG_ENABLE_Pl011_UART +#endif + +#if defined(BSP_USING_CAN) +#define CONFIG_USE_CAN +#define CONFIG_USE_FCAN +#define CONFIG_FCAN_USE_CANFD +#endif + +#if defined(BSP_USING_QSPI) +#define CONFIG_USE_QSPI +#define CONFIG_USE_FQSPI +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* SDK_CONFIG_H */ \ No newline at end of file diff --git a/bsp/phytium/tools/figures/commit_id.png b/bsp/phytium/tools/figures/commit_id.png new file mode 100644 index 0000000000000000000000000000000000000000..bf296bd1d630ddd53c21c08eb8b4ba9a71a8fbb9 GIT binary patch literal 23085 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 literal 0 HcmV?d00001 diff --git a/bsp/phytium/tools/figures/commit_reduce.png b/bsp/phytium/tools/figures/commit_reduce.png new file mode 100644 index 0000000000000000000000000000000000000000..9012cebf98578a7083cfd7aae685dcc7d33dbb35 GIT binary patch literal 17328 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 F`2(xSsc8TJ literal 0 HcmV?d00001 diff --git a/bsp/phytium/tools/lite_tools.md b/bsp/phytium/tools/lite_tools.md new file mode 100644 index 0000000000..0f807e2d28 --- /dev/null +++ b/bsp/phytium/tools/lite_tools.md @@ -0,0 +1,44 @@ +# 背景 + +- RT-Thread 中有大量代码平常是不需要使用的,这里使用脚本将不使用的代码临时删除,后面又提供了一种方法在需要时恢复 + +# 精简 RT-Thread 代码 + +- 首先运行 reduce_rtt_code.py 脚本,用 -i 指定 RT-Thread 完整版代码路径,用 -o 指定输出 + +``` +./reduce_rtt_code.py -i=/mnt/d/proj/rt-thread/rt-thread-base -o=/mnt/d/proj/rt-thread/rt-thread-lite +``` + +![](./figures/reduce_rtt.png) + +- 进入 rt-thread-lite 目录,然后提交删除动作,记录删除动作前一个 commit 号 + +``` +git add . +git commit -m 'reduce rtt code tree' +``` + +![](./figures/commit_reduce.png) + +![](./figures/commit_id.png) + +# 恢复 RT-Thread 代码 + +- 需要同步 RT-Thread 基线仓库时,可能需要完整版的代码 +- 用 git rebase 撤销删除动作,在交互界面里将 pick 修改为 d,表示删除指定 commit, 然后保存修改 + +``` +git rebase -i +``` + +![](./figures/rebase_commit.png) + +- 等待一段时间可以看到原来删除的文件都恢复了 + +![](./figures/rebase_done.png) + + +# 删除 tools 文件夹 + +- lite 工具所在的文件夹在上传社区的时候可能不需要,要收到删除本文件夹 \ No newline at end of file diff --git a/bsp/phytium/tools/reduce_rtt_code.py b/bsp/phytium/tools/reduce_rtt_code.py new file mode 100644 index 0000000000..e2c1ec5d62 --- /dev/null +++ b/bsp/phytium/tools/reduce_rtt_code.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +# Copyright : (C) 2022 Phytium Information Technology, Inc. +# All Rights Reserved. + +# This program is OPEN SOURCE software: you can redistribute it and/or modify it +# under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, +# either version 1.0 of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the Phytium Public License for more details. + +# FilePath: reduce_rtt_cde.py +# Date: 2021-10-14 08:19:30 +# LastEditTime: 2022-02-18 09:26:24 +# Description:  This files is for install phytiunm standalone sdk + +# Modify History: +# Ver   Who        Date         Changes +# ----- ------     --------    -------------------------------------- +# 1.0 zhugengyu 2023/1/12 init commit + +# +# ./reduce_rtt_code.py -i=/mnt/d/proj/rt-thread/rt-thread-base -o=/mnt/d/proj/rt-thread/rt-thread-lite +# + + +import sys +import os +import argparse +import shutil + +src_path = [] +dst_path = [] + +dry_run = False #True + +def append_path(path): + src_path.append(os.path.abspath(path)) + +parser = argparse.ArgumentParser() +parser.description='please enter two parameters and ...' +parser.add_argument("-i", "--input", help="input PATH of RTT", type=str, default="./rt-thread") +parser.add_argument("-o", "--output", help="export PATH for RTT", type=str, default="./rt-thread-lite") +args = parser.parse_args() + +rtt_src_dir = os.path.abspath(args.input) +rtt_dst_dir = os.path.abspath(args.output) + +os.chdir(rtt_src_dir) # change to rt-thread folder + +# append path and files need to reserve + +## root +append_path(r'./.git') +append_path(r'./.gitee') +append_path(r'./.github') +append_path(r'./.gitattributes') +append_path(r'./.gitignore') +append_path(r'./ChangeLog.md') +append_path(r'./Kconfig') +append_path(r'./LICENSE') +append_path(r'./README.md') +append_path(r'./README_de.md') +append_path(r'./README_es.md') +append_path(r'./README_zh.md') + +## bsp +append_path(r'./bsp/phytium') + +## components +append_path(r'./components') + +## examples +append_path(r'./examples') + +## include +append_path(r'./include') + +## libcpu +append_path(r'./libcpu/Kconfig') +append_path(r'./libcpu/SConscript') +append_path(r'./libcpu/aarch64') +append_path(r'./libcpu/arm') + +## src +append_path(r'./src') + +## tools +append_path(r'./tools') + +print('Source path ======') +for path in src_path: + print(path) +print('====================') + +for path in src_path: + dst_path.append(path.replace(rtt_src_dir, rtt_dst_dir)) + +print('Destination path ======') +for path in dst_path: + print(path) +print('====================') + +print('Total {} items'.format(len(src_path))) +print('Current dir: {}'.format(os.getcwd())) + +if dry_run: + for i in range(len(src_path)): + print('copy {} to {}'.format(src_path[i], dst_path[i])) +else: + root_dir = r'.' + rtt_dst_dir + if os.path.exists(root_dir): + shutil.rmtree(root_dir) + + for i in range(len(src_path)): + if os.path.exists(dst_path[i]): + continue + + # do real copy !!!! + if os.path.isdir(src_path[i]): + shutil.copytree(src_path[i], dst_path[i]) + else: + file_dir = os.path.dirname(dst_path[i]) + if not os.path.exists(file_dir): + os.mkdir(file_dir) + shutil.copyfile(src_path[i], dst_path[i]) + + + os.chdir(rtt_dst_dir) # change to rt-thread folder diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S index 0a611cbf48..6afc676ae3 100644 --- a/libcpu/aarch64/common/context_gcc.S +++ b/libcpu/aarch64/common/context_gcc.S @@ -24,7 +24,7 @@ rt_hw_cpu_id_set: /* int rt_hw_cpu_id(void) */ -.global rt_hw_cpu_id +.weak rt_hw_cpu_id .type rt_hw_cpu_id, @function rt_hw_cpu_id: mrs x0, tpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */ diff --git a/libcpu/aarch64/common/gicv3.c b/libcpu/aarch64/common/gicv3.c index 18fdcddc7f..35864fea2f 100644 --- a/libcpu/aarch64/common/gicv3.c +++ b/libcpu/aarch64/common/gicv3.c @@ -45,9 +45,9 @@ extern rt_uint64_t rt_cpu_mpidr_early[]; struct arm_gic { rt_uint64_t offset; /* the first interrupt index in the vector table */ - rt_uint64_t redist_hw_base[RT_CPUS_NR]; /* the pointer of the gic redistributor */ + rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */ rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ - rt_uint64_t cpu_hw_base[RT_CPUS_NR]; /* the base address of the gic cpu interface */ + rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */ }; /* 'ARM_GIC_MAX_NR' is the number of cores */ @@ -737,7 +737,7 @@ int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base) if (master_cpu_id < 0) { - master_cpu_id = cpu_id; + master_cpu_id = 0; rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &master_cpu_id, sizeof(master_cpu_id)); } diff --git a/libcpu/aarch64/common/gicv3.h b/libcpu/aarch64/common/gicv3.h index cdc7720b37..fbcf3fb4d9 100644 --- a/libcpu/aarch64/common/gicv3.h +++ b/libcpu/aarch64/common/gicv3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -18,6 +18,11 @@ #if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) + +#ifndef ARM_GIC_CPU_NUM +#define ARM_GIC_CPU_NUM RT_CPUS_NR +#endif + #define GICV3_ROUTED_TO_ALL 1UL #define GICV3_ROUTED_TO_SPEC 0UL diff --git a/libcpu/aarch64/common/interrupt.c b/libcpu/aarch64/common/interrupt.c index e30223a696..dc142dd9e8 100644 --- a/libcpu/aarch64/common/interrupt.c +++ b/libcpu/aarch64/common/interrupt.c @@ -109,11 +109,11 @@ void rt_hw_interrupt_init(void) /* initialize ARM GIC */ #ifdef RT_USING_SMART - gic_dist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x2000); + gic_dist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x40000); gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000); #ifdef BSP_USING_GICV3 gic_rdist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_redist_base(), - RT_CPUS_NR * (2 << 16)); + ARM_GIC_CPU_NUM * (2 << 16)); #endif #else gic_dist_base = platform_get_gic_dist_base(); diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S index c1f14c28b0..112987c88d 100644 --- a/libcpu/aarch64/cortex-a/entry_point.S +++ b/libcpu/aarch64/cortex-a/entry_point.S @@ -120,7 +120,7 @@ __start: adr x1, __start /* install early page table */ ldr x0, =~0x1fffff and x0, x1, x0 - add x1, x0, #0x1000 + add x1, x0, #0x1000 msr ttbr0_el1, x0 msr ttbr1_el1, x1 @@ -130,7 +130,10 @@ __start: ldr x2, =__start GET_PHY x3, __start sub x3, x3, x2 +#else + mov x3,0 #endif + ldr x2, =0x40000000 /* map 1G memory for kernel space */ bl rt_hw_mem_setup_early diff --git a/libcpu/arm/cortex-a/cpuport.c b/libcpu/arm/cortex-a/cpuport.c index e3ce568243..ec523f2aa7 100644 --- a/libcpu/arm/cortex-a/cpuport.c +++ b/libcpu/arm/cortex-a/cpuport.c @@ -13,7 +13,7 @@ #include #include -int rt_hw_cpu_id(void) +rt_weak int rt_hw_cpu_id(void) { int cpu_id; __asm__ volatile ( diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index bfb3b27170..6fd74aaf76 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/libcpu/arm/cortex-a/interrupt.c @@ -100,8 +100,7 @@ void rt_hw_interrupt_init(void) /* initialize ARM GIC */ #ifdef RT_USING_SMART - gic_dist_base = (uint32_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x2000); - gic_cpu_base = (uint32_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000); + gic_dist_base = (uint32_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x10000); #else gic_dist_base = platform_get_gic_dist_base(); #endif diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 658ff5a649..1283686439 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -208,13 +208,22 @@ bss_loop: _rtthread_startup: .word rtthread_startup +.weak rt_asm_cpu_id +rt_asm_cpu_id: + mov r9, lr + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #0xf + mov lr, r9 + stack_setup: #ifdef RT_USING_SMP /* cpu id */ - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #0xf + mov r10, lr + bl rt_asm_cpu_id + mov lr, r10 add r0, r0, #1 + #else mov r0, #1 #endif @@ -300,6 +309,50 @@ _halt: wfe b _halt +#ifdef RT_USING_SMP + +.global rt_secondary_cpu_entry +rt_secondary_cpu_entry: +#ifdef RT_USING_SMART + ldr r0, =_reset + adr r5, _reset + sub r5, r5, r0 + + ldr lr, =after_enable_mmu_n + ldr r0, =init_mtbl + add r0, r5 + b enable_mmu + +after_enable_mmu_n: + ldr r0, =MMUTable + add r0, r5 + bl rt_hw_mmu_switch +#endif + +#ifdef RT_USING_FPU + mov r4, #0xfffffff + mcr p15, 0, r4, c1, c0, 2 +#endif + + mrc p15, 0, r1, c1, c0, 1 + mov r0, #(1<<6) + orr r1, r0 + mcr p15, 0, r1, c1, c0, 1 /* enable smp */ + + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + bl stack_setup + + /* initialize the mmu table and enable mmu */ +#ifndef RT_USING_SMART + bl rt_hw_mmu_init +#endif + + b rt_hw_secondary_cpu_bsp_start +#endif + /* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ .section .text.isr, "ax" .align 5 @@ -616,50 +669,6 @@ rt_hw_clz: clz r0, r0 bx lr -#ifdef RT_USING_SMP - -.global rt_secondary_cpu_entry -rt_secondary_cpu_entry: -#ifdef RT_USING_SMART - ldr r0, =_reset - adr r5, _reset - sub r5, r5, r0 - - ldr lr, =after_enable_mmu_n - ldr r0, =init_mtbl - add r0, r5 - b enable_mmu - -after_enable_mmu_n: - ldr r0, =MMUTable - add r0, r5 - bl rt_hw_mmu_switch -#endif - -#ifdef RT_USING_FPU - mov r4, #0xfffffff - mcr p15, 0, r4, c1, c0, 2 -#endif - - mrc p15, 0, r1, c1, c0, 1 - mov r0, #(1<<6) - orr r1, r0 - mcr p15, 0, r1, c1, c0, 1 /* enable smp */ - - mrc p15, 0, r0, c1, c0, 0 - bic r0, #(1<<13) - mcr p15, 0, r0, c1, c0, 0 - - bl stack_setup - - /* initialize the mmu table and enable mmu */ -#ifndef RT_USING_SMART - bl rt_hw_mmu_init -#endif - - b rt_hw_secondary_cpu_bsp_start -#endif - #ifndef RT_CPUS_NR #define RT_CPUS_NR 1 #endif diff --git a/src/mem.c b/src/mem.c index 79affcaa9b..6beede9f6e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -91,7 +91,8 @@ struct rt_small_mem #define MIN_SIZE 12 #endif /* ARCH_CPU_64BIT */ -#define MEM_MASK 0xfffffffe +#define MEM_MASK ((~(rt_size_t)0) - 1) + #define MEM_USED() ((((rt_base_t)(small_mem)) & MEM_MASK) | 0x1) #define MEM_FREED() ((((rt_base_t)(small_mem)) & MEM_MASK) | 0x0) #define MEM_ISUSED(_mem) \

s84Y63JRC~a`L;5udEM!i(v712!PQL2R)wutkFe>s|nCpAhm|Jn2)4; zu>8u>qEeMmGfCs_{n8%b#ui)DX@?9pFS%iJmg>qy@Y!G6_7gvBxl)JUX4PiKCouxd zC`Q@tw=2?Z6HN~Ng)S(Guwq&L)9q2e6ww+2xMuWQ7CH+A%_YC0sbj`MquMi*|Df(? zDnJFf`~C}cA5?*%%b=}n0u7k;TORC^Xf|Rdes{a(O7O`IiZ#-}_9gOm6&&|`cz$Wh z-{bWif_mJ>oQe7OQL4O=p!m2+yB9Tx#0J%a2YyDF7cZbWFMT#RyA0vUggvZaB7jnW z?t#mY=j0f>gqlr^mQ&EBU!oeA}T+-1p7B0a4PUP zf`^Rt%^nzSw|vyz z5O8HPiLYwSvzqE2@P?bL3@nH*lJw>Jx5>Ak*5bLLJ+YrnztIxnJlpy}(T78-Yr$B# zr$0%ad&blxR#l5Gx6$a`;C}Jf$YM!(fh#^Pw>c_qxLohV_QiA(5Bd35>z0=nB&AcA zj5J)D0!`Y=#{{T$=5Z+Z0}&l#i@II3$!JgiJu}V~)Nh&kFdFG8qq%N%s|3P4nmH() zm?xAe2SkK^gE|>MMLKU&SX3d+1lIcPvYAeF%~{c0!PvGIqZ@0(!w zj&{@2kCtTqHR;9k7th{FF0v4qaA?cYX|P#t^HP7WLVBk&%^( zH9wO_%KWw8<&k%ZoH-uf-cM@24vQjIHIrA{>A343@|MT-fb4A+oI>?txeUB2`4Vot#$2&m#fMX{};bIGK-UPcH4eV0yj&u@Ag{rwnf%+M_taOmKAIB8T~^D3H1d9>am*YaRFO z)EJzE%=_`{-I$03NQB%LIovo!Yushn9OpvcHFvcp$*z|PFxw-aoQqqA@-eUJ-WGK2A`qOxC&2g7gSuD$7RNn1k0HVHGh z>_-mY;to4B7*bg*=?U_|&FQQ7ckIYjBx03PBqQig9-8tZK8;SQH8Wt?q=fC+rw(mw z;Zmzfp>#Jmz2$ptf1{xhIZD&u*n8hK^M_Nd+cv&r$?5&A7XUkAISeM1&(x}>jFecy z>O3=!54tE$(&QL|y%qMahd4rLmdsCYISZ^J-B0pfa}G zf>T>mOk)KUYuj-@_Mk)S+$xcg$j`(3X5GnG|15I7W}UkPfMw4>k_%g>R(ocJyLIV2 zg-_~#a=;Ys9tc{s9tVG{NH3djpt}>$kQ>K)s(|`;v8y zzhxy4+xHY*Uisu{uK|Gs?+d@*ys(+lGwD*5c~@CqHjj>Wx3uw9RJZ}=5pZ`VK+p!a zTos>ot1DMY7;~u*d)V^RSvv~TmaF5K0Rk*tZ5+|mf&T%ky3w{Dm;c*42)W(0_6c(K zV%~a0tIxr@lov5HBKM^Ib?el@rJb?;I5PR4adq53 zkJ>lpC`P6~?kojJLgU&cUPBglKAt`9%xVW7AWHC_0hDg%uV)o8!m?r4lJu$Yj{2C? z{8f*fT%9*1NX6m}Hjas`?gdbBZY6Q26TvdoI5_QF*9&Mp>lgT)O<}fjqMzG>w;hUe zb4$n%V?82FZ8zfpUY0S9Of-rpOttV4?EG~hx(w10`ARqs&Sm%#Ag<7FRMK;FN727S zPWh}hh^|2d!?I?HWQF1Qw3AS7dw_`y8pv4Yjd>n9Tpst?Xxp!QfYP=$6du$uQsek8KvUSN8sd<=rc;@pI9mWv3KMdKVx=aI4ELm+7g6S?L|qQyXntWm_6#Whvg}k6J>PFIcJt?}A4gK= zW(v+UehzK@T+8R9f2BvRh$oEQ+}5QZE%=FGOdtiKvG(C{Kb@Xy+BoN{J(>7G9oYH^ zVAYV2^&b!19sW?X7BuaIN7YSfoyuqAY_xT;UxoTuXE_^<`c7?C{Reei*xC3K!JnIL z1*e~8tIKs;T)TB{06HOy8($a5vG2Qh1Ue=?WeUDUAPebO+iNLE&aB;-dIqNXkOA$U8q*>)II;tH!)(WPgK3R6ffF~ zCtVGLSn_hM9&65#eMM>Zt!p_Jl+CdhU6DT1K!k2v#mD{SbS(gtDH&HLT&Ja7vUTrb)7*WwKh{fNFDgRKy z+w2XOz`w#$;J$bN^J$l5T$<6|VuA|(S+ji&?7odK;Oi>YraX9shFdM(EaIKiJm!)< zw;-?>kURP(nhT-%7|m|VxOo()1ai2xo3S`p*T(&}oMIsMdGuiPa|4q9UYP{i?oI(k z_FAB=AshSn`rI!d;}9xtfVgKMnY@ze+}nH-$tfEuq8S!ic>l5UCSj?CARxO*36wc~ z6+6-Xf7jylKYzI#j$h((zYV+{P!|4{%yTR|t(^`He<=NapXy$i?gbwPRM&>bttbPo z4%E~=UHe;>ggX7dS0w+WjB}*}kTjs^IzS2_ydnr4v_}*O3C1$v9S4GH0O$}v-YZ03H6w=o6pK1D6FA+q7bD0AWD~7ID{)mhq!CBJfV=;`f)MI3F+bX)`ac5Z0D?W(^DugVyId@kxEnG@F(3 zPA<-m&P!vCd@h?4k~9;92$dl!!{34=At<+eqK}`+D{5j%Y@D8*_2Q(Lj|AT(-TJF6 zFc`%BOdrIk<&0qE1Mh@LNVfDF@XVqC9spyRh)D4C??#b9M$qlGp0_@Z}wB=et zQggKBZO74bXh}SsEr-Ov??_H^IXArUS~vfqyi-gRsRSE0!_<#`8r4@%7T5%%XdQq3 z8Xvg$pc*dr`9*o@0RPe&%{0&f14{jY7nn7GqszjBrVccUQB3K{qu=CIU&paAjjknAG#JMg?1WYFv~|8lPAK@C1}3Ybk+V_DzR832jPFos<@X!_D(ZIoW?z{d7GF6HLAz&Xb@Q zsErlmZu1gB?=jmE)U3LvALc8c2^u1gXJyV&Bo)4ZQ|pXRqW(M6m2OwZZ(PQqX}-M` zQ^l`e-?h|DCnKK$)63>48_?Qc#R>zfmpG=R@OGHlBlqlD(U41AhwAI@3ShbJSNvF^ zDM-S(8N_4>%z-Hk)C{jWpi43+z(yE2w! z%Yq4wHh-&gipWmuQD6F`WuV)6JG3bnOYr-OO*rY?^TqGCoGy7sC8ryTXJI{J1=0bx zVMuAf=s*|Q18n^)V#vQy??hiVH88n&j>u$HJru`o7l-qT7UNf`uurYAG6dgK8(V!6 zfj53qm>gU5o943hkRM z2|}VTRu+@v8HwoH?n?V02k4`Wt6++XK7=wup8wg;%b-Tn){ziUzl?8=&_uWEhi1Sd z0e`gvNAKpuSE@j#HCzztisLX#^&oaN0$t$+U-08c4+;Jpc8(4 zTNJOV#&AR`b>q+%YAAYN(cR7+gU>~mZD)fv zD49&}Zg=|%X*@(t*VwGE>Lg&nj=*xZ-e;+lhDxgN?o4tc5N+%88USF751fd_UEY5Tkcy{H8} ze-3vkV>78=1Mb{l!f{yUy6}6C2wow8t51kE}Ny6_( zcHAmmQ3XR%Mf5FGl;=63T0(sQF*gDtKD~!NsMnVMQ zH8I_ndOXcpI+W4m0+w4Q5nJ~Lxqj#VjG|sgf?Q~~( zPBs`$CL;08GAF;}&g7kS>7bbw1EU*C5;aKGyV>Vt_8yjeSj-hO|-%}w})fm5imbok9-gz8lgO9htT%!!DI+m%c{8%7m%h!Cq(*)b2>eI$X6WAww21gkdp2jOn?^ErQ(l5G20!YjjF4}C5mzyg<)ItQjaEb!V zZ9ex5IrqQbon&6rOF;bXQb>YhIpM_x1`O!(&~PaVtF{--FI;<)zg5)zS4w){LG8}Z z4f4`xRkP7_i8cX6H`TCH!+&TsSc(7^ zMdd)h3BKyteY6`tU*;tKb>4=ekrjl)eqmU5`cXA?g$HT=T7-&yJTw# zL?-^LRTA87ufb7&o7gwkppB~_;YxWc=Kj6cQ;^T1z$&pboLMA!XO^Nga`TfWoAbwA z6Gjhj$t-|ieX%{~8UsD}pT+>Lb%U%jC^i`>5$Z)CgY$j=PlnI_W?8h!0` zdF;+v2~baeZhGVjvOZDFYV`ep30|kcJP7QD!tKid!RG0t{ewD2cdMlL5mZ(kDbcmU zyZL`Or9E1|zz!~K;sw3~*Le-~n(@ID?bGk~{Y@F#nme z19~#1>=TaDJ2P%N49~$(Uu6A$({5J5=Ux%o6!h-M-2TC7KVM&fT=08DlrE%n>$qs) z<+DKIZK3EFHoOzwgLJ2+J<*rSWImObaPZR9<7Zw>9WG8@`UbxNgtuSNwrRF0&bA*F z{j>e&uqxPQxu9)&;GxeW$D9>da6`$n^JC^+c6|j=7C}|ANMDrZqM9E8MbgN86Fon3 zu?apT=WmH5TxyfS%zwO%0G;_XcvUC#8M`TN#>L@CHUK)WLm9DWR65URFSRrJWQ3X! zvKT6k>P{coVAIwLj=nt?gApMa)6YtkUbf7;h-+`GD!lXSu*toEv^}{643-pbV4Jf) z_$SJjPVq6S+YC$sUFt@En?Dshw}%g0C*aCe)`y{H0nvF<;}47iP2&v(wWBzqWL$rm z1@}H7y+z=B*UI|dqJ*meruQU2vxv**lJ67OO`4lgB%WIz_wshzBC2&GSZWC0cZ;UI zo@PyR@%Pl4-AGs7xp`g=S&@RkH7!YzQl@dHkR<8sZ3aa4HzIX zNAGTgyp=Yz8tyMm6a+R259i@kUZ&|%(XyWp|XBU{(VH_B%OX47Z z5~>H-0cU)<^%JZ)&3e-|gT1@fvueZKY(W5!7+%wb**~k4d3+ksYGBF?Ny?2GRFoqr z5DTb)ewCEdB+KzD;&Ao#EXR6XKaBQf^&85Huxq*puxd)a@6%dq1(gQYjo9a1W04j< z!hOmN-)wfgrpwRmn?vF}H~$`q*T%dYZt&C(O|$K5ScdNP?-}L&vuRdI^tq4rOCJd0 zn8Nzm3}})Y+sI1;y9!tkvMY#Erbc3)sS$fBD;_Kl4%7xgI4EY!Jh>ergwW|*uUz-I z0A$lnFf{qG^P7Hm)+udh@+tn|=#XL}JTKSmi41&JFIPfzu&jC!to$>{otk@h;9A>@ z#!$_0u_x8EW>ZWnbh=irZpWc`{)r2M0l|cOgetlbcHLT02 zx&9Y#|7>YJ&3ELh+mPlt5s3V^Vm+cqkR+DxgP&wcN;g#KD~!jh6g0`^B$N&W^Bk)@EID&Q(FBlOScCMyZbuEEg)wN!}`8=Fj$gjnAg0K-sF+ybH zx0h=$SA$%j&T>ubZ1oPTsG-sJ30i*UH{c@<9HVdC?qwf!v&)+*N}soXX?ISuI~Pi? zq!u3gB3&iEL~aQg_IXC`*P&0B+bWdo=vD?yw&6UBTDomt7Om#=zwI997XqJI;4!LKLj9|boS-9TbRf@iR z9su$b2xU4@Ft-2O>2K}zM}^mRMCkMpltcI#o%&bV+|8FO9;m`nF5_ zVLD6L*Y-YP^*zK_on1xV62f|m0Syia&rVOz0}&sWe_{@@_dbzT519VS=nA260_Yb( z$$i9DlEHCoo8j=ev_N~kxG`@`N_z0|63Afjor6o+D)I55_NI>C_mz+=Ly-6UrYzx$ z!)lWqs;SMeGiQN9Sq7jOislnM@P~ zVB+o*#c?WVgJ6i?yB;V{TdF-Unber7Rz>@#nBWu5X_s)p!k*A5_1s}98!P>F4|t$p zn){~4@d4KVUTTw_-t%RK+Q>JDP_wFFzn0djN8AeXB}yH>guvQ8B)~r?CnGTK1$L4w zEWonw?}azs+K)tb#0?F_yUu(z7LPt~`Bc=+c@w!pY(PiQ^-F8%S4Q@%<6CgRE5g!6 zJ^y4vw-VWXutb&j>v`N1;?J=7DwXsT7ud;+0EPY#IffNjo|psYd%^!^(h4s7O{4ZU zWG?%OU=?BLEF-shF0U10UJ4I)yDFKDcPo2;sqiY}`m)l2arI33i~~fBh=|!3t+`Hp z*Ty8(at4fztvAtSY$(Cn-oEq=U_0$0KzDxpzLOKe&}EEy>QGDrg!;JINm9T~Rmk(0 zpwp`L43A)o^~Lw`FH^;y7js9c)LV8S?u4`&CPQP7LiQz;e>nPuVV8xDx&}3DLdWpNfgU2#RgufLlBY?I67Z{!w}3C@^1HFWY>BnO~}`MRn#}E$@h$cTjx&+ z^V?v*>_?MHzUZ8wz@PDvHi}Je*RC9-5NVXs+#dm3%iv_@*}PRBM2JxO?28&HK=!d_@)`P;&E?rjMrqCK`1!XM~mnqE0$;Apyc za<2Rgq-w3`wDWS!lnDs3X9QG!m)Oy5rnf3cw#-+C#6dR7$R29HtaZwilK@S)dhtbT z9aOHdS7%ZQ{t8Bm6&934`Zj+NVLdE>Hndf65jL!shuX1|k(z=l6*l*+q8FELEYw(W z!H`+5%>*NvPEc>e!&BcY@To#u@o&4w2Sw~AHd0AgD-z+r1;r&}od@15D-}r3!(T$| z68B~S`MP%3$aisPF@U!ILDe?sHx3`@E`F+%p}QLi9|PrWw9%2LWetjhrJhy zdB8POulwKXke+x zvN3USB=wlaCew#GKDHLt^(b9h!JP8&6RYQvucP6+lnIzb{;xYc9!4XoxZ3&h#J_H$ zdz-8>D>Ja0oG5OFW^B^xRaGmO+e?oY`I97M$|g5o)*Ij^js%q0KBjon{9*J}uO&>~ zrg?tOFL~7yt25-@tIeo2aYM@Oj%<8qaZ%lc-k6K9JKhlC7( za8_Jl#kpd;w9A%dw#_b5Q#vM)@k+b3Hne8$BD>Z!w)ez-QeFa~06HAl@JhFtm5%t5Z5)*4D@$#Uq9ZG(5aa5y(wv+_Z z(DmfeoPYt({aW=kxj9X7jYGqVyACl``pbKVKI5cGe<-}!?R5Is5Z1V=NGf38 z!uq@K%0?IS+C_$M$8wD-6vu2Zm`zgO3hpVYGAD&jRZqrnAuS1x6 zL;3x5>b&y@{$_kHFVnfTGj=ZVyiK+3WIbbh*Rx z11K7$p6HDlQVp5lH|MTX+s(2&k2oyvNmj}7DW)ekF1DHZje&0`+?Sb2%XA15I*Sr4 z{_GqCJfE=G=jI`Pp6AB&`W6}2wtd>7OXgYvlnUw(#F%RR85Fn=JDEmNP~LWTJ&Vn? zP5bEyre39C8|$SV#?oN;;%pT^v75UhhJL=w0_4SZI~(25=&rr7;{zeFfb+&so zSNK7hlX0~J=A05E0XW&rOwMd_d07k8>ELI0_v4!FkIR&bj%t0G$AHJYUaF|S^m#N47Q z44zbR_ou>!UBP$q8ODryjn;PjB=*UV@OeCJ}IK5n~ zTzFB@M~!2@Rpj+OWP@^9bdSa$ss~Y6Or=iG`z`6vEAx4d4|Vy2h6s8FAgLiH(RRW3 zGAyWY8rZBAo$a9shFrr2Cq3qr4{g%Vvf}VsrF`t- zXO0X41K_;=SrbiNfCNaw)@4z^74_`P@%6M3;-23+u)PZ>B@vOHYr;oq9;n6}|gFu%N>`i%&vo+3ZJ`7W!TJR2X91*xf zQHJ|X!J8xCp?5m&Wf3?>B3KK)O5Bv)Dm2()B?cbw|0G*}kKR|4rLF4KB?dtCxJ;HF zF#O@&J-;{iHoeOOvf@kFsAV{xTFtC-ZC6U~M_+JsirLTEd`U?5Y7RLK-amrAYkUZk zg&_X8GGeT6PB46#t#O*jg_Py-b}buQdqbsU5c)5t1Jrj#>mL$J z=)buJOC;GSZ_8;fk6kw3{{)a=3UNUtb)G;^8C{-Qv{*ibQ=ZKr?99>rD>glv2q41F zNUVUYUxl6%CBuwTwGnq=(b15=c?M^~h6(F^QT=kmc|Ls53+&#`6FzrqwW97R=VG># z3)io%uEMb?d&9cqaS3YEvmNS?&C9ciKDnNW;E^-aQ=OSeAB(j0w)+6}&)pu)q$pt^ z?+-B=SqwPlNQgvfVq!Z1xRzusW{+XLeqEkj$9D3daP0PV9~ip)j!+6f8eu%tU1N^Q z|NbGb;QmcRk$>Lo3*{#@T*x>$yTaPT^;7v?_Cv=T*V3OldV=>?n}catTifI}^N_uO zG-AhPuJQS!4Y!=jEcsyic&>+=k<$Wu4)$C-c3JG^Hy?l#*W0J*j(QQGAx~lkc1^#*NsIOuzH{L!$#Rf%K+yvIk?d5PDSx zbw(o_0mTwmINrYFCd)T?-Sj1SLm+=^@(CgH{A|u|)cXaeKt?0J;J4Rq>99@yo^4AU*gke1!eY2=ZF z4o5%VY>Z(aQmQs|kO)5QdB!le7K6WpJO!Usra#&Xk$-kZ!wzB?-moT$)Zx+eI+5_Y zjzouVC&GWcto6PlN%_AP{%^Zb zSD{xcH|$liK?FYN&v)l4jpBRC-e2{@jr=qKDu4#9bP`~hFQ8X%ojVeshm?U*er1Y? zun=lLpb`Sw8*qd=UQB|4oKNoN5KH>S7-e_xZ5-2i>Gt(>qklm?C27qBIcW>b5NL{U zrUw|`rST-7>Icd-i$O{l)g?j{V8w1notP zaGu0d(iwmCwITgQf?7bcSl>$7GxgsOn?wU*%is2nXrN((p3qw%{6M}b3Vu0eXzOAP zp>rcrJp25Zi!+@!9IL`;DheDIf&V*90=iu^bl#vb2RaO}^r@5L}dKY4yf!pmB)7=u6st%EajD26{CLhBn`O zbo)FhRBbALQh$Yz^R|pA;!y}(=;F%r50ZAYpE>4vnw2FK4Elt(Lw+n?l$@C&vL@Ou z#o+GkpB))Wz)^ufKMHJ#(8T z^hhWO@rpIoEgg71dx>K|&T2H;coHcMm`neN>3*}JR*I|PNdZCAaMHmu&5kg9mpz}E zNsB|!+x_K$%DGfcHHn18vXO;opsNki!7B*C5cA%`GcV6g_mD2K2?luwDy@EW_E~{9 z+K#+rd}8#K?wXRaWiBc~H72Ga0~xy>fbLDzb#N4JN980r4 zMr0{r;t*w=cvtZMd=0OD&GhXcUXX)Xw>oeemtChC|c%zFZLcA>~JaHkNUTrs*_L~n~cWs8` z>ot9!)4(Fot-QI3REW2I;HC`mPx20+OVjNQH%R8{Z!mK^*qc6`i>jy}QT`rkAS!>o zbSCyV?Ed38A)flBAQ&V_q!+%UrNTJ!N!StQ+Li3;FoF8ML)y9)Vi^96&_!A+{FIeZ zEGgJ&siUQocGzFmj{w*n{{0@{s7Ctu+vNwS{VSN8e((6o!jW=<&y3--I8)*VJImjD zLk$lag6W{s=Sc2edb+?<>NxneuTW)3Rscfd34T$M{*FWMNt;Ap2hbOebZn2bS;+1l zj9ql>U2MOICTGSry)^L4u8qYPzmfPzzLD$nt3DlZv`#ZB9c@E+n0~Y8Ulgxi;ON5+ zVe5V}Th5pFlhp}v`ZQ5!bO>;GEn1JIRQ!&OmgV`WjmI|<6u)OKX{t!?d|zXaceo=Q z_(HlUp$_H)ZUK_0_2l-PM zd50J+4uc0b9c*rV=~Rts+Dk1{p-d;^_8FCEsZ}4JrkB&ANW>nCow(9cGKAX=^Nuxk z9VRS#{N}g$b>iwdftd1b@*``!QOwb@OaH`@tt1-C;5_U?=@4b`WxoPqK>x#;8o7kI zu=;^u?hYMy2Z_=~o%Nlu*K`)RJ-wnfnFkH?kVw!1#?`eHtZ z2x)nm4>vzJ;cO98A^Bxx+g&#%PhR@N8EvA@hER#nk}vy!vvtZ+$7Wkm>3i+m zj@`(qTVH+~2=!~&i{5KDWzS(*gOZxrBD~%!hekd2Qh2}q?UnSA=k(hl(?*1;u6C<{ ze)ivU4cZ*($s4TiTw>VBwV5A$A#znFS2(C_v^K*^6XF{rj?eeu^1x$cioJheKCQmnzh>`H6vCsglm3D`EAB1b}UN zdbZ&qQ3lbQ=A5ZR$guC++xK1b7ySY~?WZpAV)RtlYEg~PB%)U94-8jT#$Q(cFg2(v znu86QXj+8~LHA{6C-G`@wk2ymNAkj)VB1$b&BdKa-bipwf)%YE%)@)lX+q4TI8g9K znrB6h2E%@ec#s!4iZ_NrHWFe!&MQu3fvYGZ-l57Xo5VeaEuv5~h_buz{)nG%Rb0M%OU6}~Y(rs{k&1@n zsV{*b47gY0&6`fIBoZ$-N_v@UicH??A7x|@XH3%XQii>f%!OxXkbjdS5oZ#5am=Sm z!oKxX;lgM0gbr4Ok>m}6LrL2(Pj~~zwV#sDyQ9UjKOCa+4883dB?*TXZ+%d_^aYw9 zqsN9y>9ovCh+s=`cFFcs$PyVv}A>!?Sj0v z;s84vDJf|Ko)^DC+vM_32OHR;wUU5&$rl$$nj}<$4yG*0wfn^QR7xt!xz+=Y!ie$EN*J|rN~JmyO4AQ1Qj}p0)0f#! zn#7*Xctk5~D)r*hpP=Z&|NagSMyuBF9%;sXv}TDSkB$im+*CndPvZ>pb-d^7t%}I` zFkPb2>7in=s;?(sNn+9L*~$Cd+AOn%+Ky}**N=p~lAq#0#BK5|wHU8{Ls}rINJ}?T zKGJ?fQWaj!mY0}zyw$U^^P19HXIIei?1K5vFl7d`-`kq^dP&@&_~+MN0Us>3%V2@S*41L-? zf-X?E;cT%w8r`12&XYdI#ns>BiTF&msJX}eKR@Nm9_P{R{^oFdsbqHF>o7ocog#hVs*0YUV(ab^a;h2lJ;g# z-hLc^-zxUP*WNgS?eo1hH$cPV{@eEvcU+Nu1GOeS%~fW7AucD#`Sosy+520L8cD|V zea!FHy#k&0&AE4>#&rb>Aa8xHin)Gn_BSU&F!?bdUHG_7xbiK_xU!MVB{#}%hlAS zy2PRwR^O==R*1>f!+^)~hfAK1LvfcRk}3b^gwsV8HdTD8(<4OI9nKkc9yBS*Sf1ce zgL3>{p&_6xQ|f1&iH9oH>11zwv?l)i3Zkhx|90Y}on_$^{q39cX|yre9}4=8x!vHA zel%4P(?Ho0cMz}z#9(vcdFAn4<+EOI*)DAn^<(zVO1_ zQ5t#nJ>F@TAy4U-GtE)lNy^x-v9B(jH}BJCsCy8Fsq`BC8AIJ|Ow$2{1|2+AC_FB1 zV^>dcS})o>+;)?rTaqsk;`1y9^<@AuTkyTOYMzq}0;cLxr|!MK@_qaxuXf5Yln3*XuG9#_D&ZBSr{2uF{06 z)~u~Y<~^n{`^mR-Us>;MDq{G(y3O9cyh^rxVZ56D#w(Qqd7!_H^i;zYnZ`imO43onQS)`fze`*0(>60`pd84L!B>W_`Jnmn0Fmp6nvC`6pGM827{eMpI`spr!CHVT6*P+ zli9dS6MphSbs<16!Qc0^u0a&V3ytJydgKs47O8HB`|Ehc4(F0V&R3W2L@nF%>gWR; zC!Zo~$$F2VuXyRIcKsg9w8X*Z#+n^ag}duUZD}q!LQ^1DMW4{Vt?ZEl^sI*YRp@O` zdQIs!nar5*YV&Q6n!Yb>q}XpJhg>bsy;d4orB-NSx=HDzI)}JLbD2ZJ`efBN!Y!5B zh+1OUt?{>X(YKqnshk|#_w54bc8qKDQFp4eZ{Xi z@Mg(7bgfJ|C@tU~6}@btz?oDof?h9tWF!X%5a}e&Jsyh^=<9h~a=B(Zksr-VNwqcR z#h)_OW`+DICb}BEM~WK0fguR*IRWV#wzw~q=_2@lPd|P*=@vM!0OOWufOWE|o(2Gt z`tFU=e5AQr;epLEwwm~qXgu!+Aj-<0%<>&+kUK)vXw9W%!)x}ylmrSOT$1q9teCf_ zu8x766%arJj(R|zOCe?d+4~Aqr&1TBn83@f*8`w{hm_iBYY5yBx~PH5gBHUCFQx=M zOtCshNtLnp)+E?}0J`PxG{1O()v*6R0~CPk0zT`pe8(_#$r71Ylli_BFQt6~$YYPl z*XA`(luquG+LuTjz1EW@EHcvJU{WN9+B(agH4hIup8_XG}0f@kq>&fHMo09ZjFkR>ZhRAHb? zKrz94yEM%9lmFBai3Ffvn0%amFzFB~1lL*7n6qT6ij1ED-sU}Q0$>7k&F*yA%M^rX zo-U~cAJZ%lHz!J-H;It=3e*nhoQ?2kR$PFrTfjl2sO*PQvk250YmbKb+q0@0!!h;g z;J`h;1_}(pnqyV_yXwDoYACs0JRiL*Y4sFS^SQ$e3>bq0q!$w%I3^;JB*kMjuiI$sAWj|MYR(K3 z0c6Me6&qF_+>OtO)`4x{_Majcm0eK>W?n_fiO%0JiN?}ZxaYwyvqa!(%GM%G1{vOb z>e&8w%lo^>(&>DtF;878&{Z(T*P(#zGsw2ja(p9GB|f_yhT~1mV_c9$Pdk#Yjrbgl zUHVNl#<};Y%+}kvq)(kovf>&D_dko3Qp?Pql37*L=8V_0ZG!8$H&d{~X^$_(0?m5> z)C%TIP3Y$f;pH>d=mNxy<5Y$G*A2i5xd`MAD;eDd@@USVq$p{tcH-%6 zC9rg6pBEMJ005_=t#}5dyJCuJe$b@MOEBsK?7NL`52uQf_C7~(xm5D)e+_NfPSK@L z@FGULHm(86;tD>^RI+f1TQN^YFRm1G@Q%>o6k7OCyg!S4KF0bvJsd`pPUNmUiG6K2 z>HXV+5#D=nCczZdVQ-1Q1b!K`htc$F=H=G!17YEXPb=xN3L?M9LafC;t9jFh2_9%% z7nT1KI{*tHJ@sklp989vr}KC7S^I;-1E0egk_l76XlZ$rZJCUglSt{N#$MB?_Vb)A zt+^-M9vVYE&*Ec_UR8M6POvmPb2{FHyomLEnOrtk9JK;^Xa2!}q|u)yg-6n!3Rc8& z{+0<7iwU>}6q`D&7g)`#hkypiA#lCD03D60d(iEfzfQoWzVkNylSSYXavECu09f6kP1OO(NOvE6IuPmzkVnZs@E+H}5MELd${r7e z803Vi=yk4V$z@@`=a%R+QuZ6Gg|COb-~7DyTfy+FX?e^5=8G9AV)S=22O@v|#9j2W zuu?z_9dA*Ia7*U9)AraHFH?K@Wr~aaW8^+j$ZcZFo)(v7wIdU z4Aff9uz_O_?-=4Coh^i<)UBgJ*;Kz`uvelmj?@l5$@yHK2;Tz4GOmK=;7 z8{z3+*v@sG$cvO=XF+duk_XjKeUl{=%SKaRZXhIdIO8+t8o6tp{2Ic!{)TI0 z(QkeOoAlidDmP?v@P@wd(xt&dE5;!t&-7RIA=muWo!-SdfT9KDq@hUDUT7Ww?x0ue z3o};l9SB?ZT|8gf3|YoUz5HIU^tbue^YCgi4JKU9bmAh0FF!A#v`dm$;wNMA5bKm| zdNsw|!{%o%+uyJUUfP&>plu|1t~g%}|0(h1@QiSdywZX74#zg4ii1iv#m%(j6pF!M zKX&#ELZevZ5URe_m(>#kvuzM@3Z-W)^I#ERx;0F(q_X^T@n&jg<(4v#1JQ>k6=pdX zwf@jAEibR*SwU&BFO@d=IKiygR@Q6mQ=1kz@LHv@EYSqN-eE{vWNtE) zWnY#X%ie3P{g$n8Anz1`B7KvllM?YkWyJ&nF}=$4T$FYgAcwJ$(|ac`W*HjgSW|vD z=#}Opml@^d%?2cI^9a52R%94@AB}mYHTovebHr0YHyQ1eEW_KV@P`$1D@Hue?d(3y zLZwBu`J(K5yv-iPHe!L{y{oJia9$+tGI&nhMi_BF8k^fY*mJk7{AM>G!ZjJUp&)k{ zy-zy+@UHbEW&1y9SM}U2n%zX+qXq|~`=+inc4r>@002iTz`?ZUWQu@&H6Vx=7!2^H zS?DP6-Z?F#h^af$O^N;Zy&{|~2l~VpOhU@Gl3F)eDmbOtUmrdNb_-YsjcGKU?7XBQ zR4;teVPdD4V+`V-Q0nbf_vK^WfBOOZQ1n^bbEqz%qjpkc?;-?#g^37&sz588hH5Pc zVjAu7Klto_YUSl?=x?`yTuBwri}-Ag=$JNDSZCku9J1c zrv`^2=(sWyIou@~TIBHHGa0&E;nI4F zcO-AD^vFUGPNbXHmb;qiOx?xygI}}9wFxMN(T6vSjCnir_wMKWzc-I$f3>MNKtJuH z&ffo9de7c0IQ@jN6eXo@U3gUbWf9iXcfsfy_T8J$jQI!IWx~U#>c3{b_D?MfvgqWO zm6~)UX&^gb=%{285I<-X6_kJoLPcCML&iYAvpxk2NIRGE-+G#&e97Y6Rk}hD++z0Q z6d6Nrft^PjdCKDxvn6bP2bp-nHg(5vnJvh8+5$|-gnQdv^+RLKP7%fOErgjeR*NUrv6Zic!Py<;} z<%k2_Lw3{F&tuY=#STO&`>i!>!F-I1Zk=VUVRF2Q)WT&kQLBP+*F^JUM~h|dJm}lH zP z-(Z5iP%*Icmaow`rqilR-I)bhVi(j>^>iXXikS4k31iL@J#FVCju6i!slbe(Ux8M#VuoH#a!13=9QX(&(e5^AYg@J|$HIZml4Zpy zyoS(xTv+L7c=hvoYB)Eu&0fTjhNN-06GPLoUv8+ z=^Bq9$wGGAir@d$-2EdGQ4InBq~)zdxY~18$D)`lDL~|vRrs~SCzdDv)4HZ8JR5u0 zF$|q#`Nafa9y*QAfZd5z`2XM^K+%ZOcK}X-tg;D}17R59c-Q|H(u8)?0_Bb`X@l_} z!Odgn1%Q-i$AtsfhShpN0YeT1R~$FcAeZFdcOj!6>VWo?ti*v|F8FXPZfM(424n`|{y?Yk;yQ84lt#yYIbE z+9l58bvCHyNqXyu^Z)Ng8R+l5!Ok7j;@Dg2AZ+b{PXVeXMwr0?{C@LRGv}H-+~?q2 zM}gPgJ}ISR4n6U_L0MLPHtn4Q3 zYQ5Us-qx}MrXE;^g^11Fc}qhSRexu74sXL(%}8wpFToz~tT|)Uyn|^81JDQ1mMmTP zEi+wn#|Wk1WxrVUb5+M)@2JEA6a-|*P8 z+nS;rUSpDqIW!aw1m5Jf2NqBj4HTW{Bb?_S41N)#LD9ac<{Sru=Cq@6%*P$3!#rkG z;|L$dNBIb7l@F*toat|C>c7jmxU+U2tbHow>Ea3AcZ*;2hY z3?MxZe47K`-OJ23sndu+0Wzis4V9F??!Nh_0}XpdSrd*Q=7+dnrn6l~l&|VI=)EFX zcI4K3KS)pVydw`Ny5mlE?MBBXLWl&M(MI-i6-IuvtqtR`n6Mk)DUdtjB@u5rD`v;v-6WV9%WR``|1%RxO+FIDvxPd zoT}qNebfrVllkoXxdb2ZqeS&!2k2jDNaor{76o*D{L}1`wH|!@)7!6xPELhhqv_N- zZ>Vq=fB47EtnM|8%GCwdJQ{xNirodS8{kv7Rl#`wW!cgo9J%&sz3M z*#JfGo)!T0@Vby^^_1hI*jFzNF~RB$(&R5-_)|i-hs&$iuSd*_gFRw%|E&mk6V{(y zyPJ&ihJ^wssBj(mi2US0{s!9;{dUEj;NV$}O3ym+)5jj;5GoT16R(GI*+7d~Mb`!k z7h-Y>t^!iK08y)+@#jXi&!KD*gorMv-l*{EKh?hq9(ItnHg2Y;(>`W-8!!KY$4qe6 zn{+}H)GmLEHJn5d<+K_$!ei!awW-Aw*K1VyM-~}^{SB462N~ayA3J~O2mJe6-H`5G z{R|jwfHCbJ%}-N3W7b}K3?oO>k*d@p0b_y|->1z_4Ip0z1edLJA(AYUHTJ_?ioBv! z7DT((HzfE>^lHw2z0EJiUaLQ*0={Ztpv|d=F5PSW?|}6rj}o|QXY~XqXdGp7?SB{7 zRnQ(Ppwc~sv|iBgtvmi!@SF#I6kYKq0)FK@`(Lrc#thx4@fdVjco)^sRK}w}R^=aE z%_`r2@^(%(je16xB^(~5n5tQ`Phtp)?s%&Y$zt#Z8($;B#La!zv3~xQ0o%I<$)k|; zwIaE>iNcyTp~D{--XT@6kzRDPR~QbEq?n}Lt?+^7-hH^>Pi1eESE8lWbA zriQoT$A8k6+1_V;>d=*_f4i?|k!9xxQ(v=gfV!DnD~^&-WPrVe2FQ*@g?9MezxyIj z30vxVdgjpY<=x}DQ%QTi=T#~_YhszJzp4O{&Dz1ZbM`Y8ABP`9d&tFMS?VJFUO~mC zb;IO-j_(Y|1)rT(r(iE!sbS^pNcP%QMvm+!fjc+1RfL^p{0j2n0puG2-LbL-h*1Ap z-A6=bzz(}3M+b#$l3sBfLvq&SMMP!6oU&Hj4l}U{b$0~-Q=s^}&9Z(BR8%T@&SZIZ zNlRT7-U#5;$YEw6HdQIHez1P`ZIbKD39Pd>An5~Az=p92NVc?ezf*P4lO*%3u7#=u zvD^uDytOT62}wox?UUwMBEZ<`cwwF;6oM_NxI66_APWupB>K0izh9v{@z+^1g%I{8 zRav53p=LBPJ6XX|auuiLQ7>Li18tTHsxo2z;fMR4h`EZfZm!{4sZ(hhZu=9vAn#RB zas{Uq60sgI7XvBQB9Qde;*U0vqg%=z!!6K!)F?=^H%eijwdYn~PnZgGkX>A|xj}1y zjxVl=*-G6@w7uK_E8%dwiL(Fbp8Az{lPw+4r*?%DQa9@{UVTq7px#@qgN-#8pJ8)a zs&JF^e<=RH%^n);h1yON#knqDoTBtG9A{>21H+$&{aAvT>AiCIWSfiDf_yZ_Ob4l7 z-n-T{e_)eGVuC3U)CRNWLm|BmOd}1_@=I*xt`D5X?|IzwVT)FV*mwyAE9XzB3PsDr zbe&l?@1sk{ah5rQrOi8I)-d=-4N8_2vuMnlEPKhgaR=YF2rnCd`)Qflo3bcpv*(Kp zJF2|$1ftPH&c6`llp7W?Ijh$+;2&Z_Xi5UsBrx3XQOXuSpr$8L3^Sf*H?p%*dIMjH zM9N)nm8A*wvl{i^qjWv7c6!5^9=j1YmI}$5C=Uun*(e0q#r-~Ql4y5d#KIjbGZ7_V zpFmntEtXIBP)1osG(X}j$;~AExwY1a-h|Jsp?9B^&b~L$`@lu}jP!m?Y!Fqo-1>wj zwtVhom-DzP$H1vqu@+udBFXaP&YtzMm3tp=&M$>7{g;hbl!k;-xAH@5)vKVhmm6lc zsoqYW1p_7G-qDQz_e-z2*{5uUWd&7_=2bo@TtS?51@>?Qfgso3h|o#>eO=X=m+$nA z?m&vGOZS(x>1i`fpD&aBTCIm`AXJ$R@@Q6wYBoFAFe6FH@aC71G=zhYN$P`K-e%#W z-inkpm7V-C#b?(SRA?g}{5|RFXF>|F_j}bawKZ3L zB};A|QnTbQNq61*NF6B6;}u-wVrqgrCaN4Ht};{hm4yf+eijV8pFDP5ch!wo2@s^f z!3SsBILN%uMDL>*GXp}=686?05Eab!D`io zF0DCrfQtL|)(cVh_eSVprkN(*3$L(J~Ynd+$gcDmO*>&bV6m z(7x2QVa?!l*sw17^r#-iPADj`VOBfAooZsZ!QdTY*U9TlIWiIZnmG3`s zA|)0I)R8RzwUub`@GR^{gAEiwN~|41Nx-{EtaSM zlZBiVt%WWmG;Ql91Y2d{>RmZ}8t$W_s%Ws_O^TfxO({c&uxSp9|(h7$ez26iWxZBUeNK4_`7Dc)I8!j{g##0x*es>B@Cs~tZ} zX@?w0ewg|@fchp(Rb~VTVDN>_BWW6y;6?Jr4qH;5V4jib;Zrcf1$lGK<)C-Fx@V-> zd!t_jDUT}*)75t0Z<{srMYLnB|Hk@oyb)IWE4ATP;{6OXFesj}Ns5)*MO{|-TW$Qh zfAOeNADg`;F3_q;`WZZ@GcXzq+ZjA3ef4-EJc4ezcA1m0_|Up9+xLdTqArmkgXPcZ z0)NZa#rh>gTHtFQ1GayRzC|~PgP06Ip$VuQAn+(`A-`UE-3`$?(=?if6^GX%cG3m_ z(b8(LOB-2`>J3$XEP4~yp!0Xonc*)0j^`Db53bocW9=~@)hZ~Tz0b!{z8i?&odgoT z+~J681E#2Zhwr9;=cwa!31Qo&{4aYLeslR(63WZoBuC@Pe&LAH-TX$=arR#jAW&+> z>}SomTv|1|E2<5I$yf!H4{;+qsiR5)JoDKmvoaH1_$K!iysP)ID|7rjxa_LsBL6k} zRHI&>*PXN^OsskT<|wrPyI>=I;0HH*XtS<#&-&6Bw&aiNYj=y?C6PfXLE27AWKqoxNcqO~6NPYVEn8+74le(FD zw!gVL>j&nxl{|gtHpwMGu-j_anrBLc0DH-Ev`fvjO<0@%Gfu(H2ZWK3dB$4i<8n6+ z$7>nnQq?VN&9{85doSY&`(3ATL84wnL?;bYsB^CUyF=8C$sw!3T>P$>K6dn-?Y_}M zW!~v5UX_xwc#nw7&^xz~6X(j!tb1U~xAHhPYg1bKBN5S~)+iH~y5g_(5>qRUyG}4d zsQzBYj66!br1Ei$^-z218a%$=2l?(rXVs8}6Pro(t<&2l&Hu;nDO`IL9dwF}uD?xj z!QNKVsyti!stLL)b(yy351`2*M>bPJqp8xgZD7_{uIiUroTxXzK?eGsGX*Kinb5SQ zJB%|IMl1n4RyZV|hojQBWt%yc-8jH+0PGP#QGh|?Z2zi*`%K@-w+459P&J-B-j(og z-=9yKRx>AL}(mB6w7IsjT|1biUe1Mu} zie>#XaQl!Kb`-jLu7B0XJ=1fq6mc-vCicJoi;qs??AVdTCl-zu$*oi_c|!@%Hua>w zu~leYklLoS-WLAQ_8iOWgHKvpYuK%J3Y4{5kc!k|@A)}(6D(fppes^u&sbxiM-u?B z0OYKM(0DP_zSh^Ga~tN;06o@vrbmC2bw_K=ob}4*dClr#{D{58&m2nFc#%2wXFQ z2XsZjYgG_q;0gjT{?Yir$pCPG+G$Rn9rEfC7oVpmwNhLFxWee}CJ8_o?7}AK-g@?2 z1HfLuAJ$pu}ZEyvy6cQC=L{Vym>IYY`KEmCQ4G?hu2=!-n-t? zJb-jGZ~4II+>f$&)j^W^NJ91lbjZ~y8a)JO8jfMC~)|x>3bGq;HxeJ8Ra~~@@iKI57$1hy5 zWc@amod|q?EB8b!-7iDqz73SFZt_uOrLuw3j280$@^r z4(RaZcDDD9j3un6wYU1Ze8i}e+6^&~l^Yo+GP-|^^PH^33zbcEsK56Ku6FKy2A zpJ4lEu3Ovicqk4^x*tzg%g-or zPL2%LJ{A=<>+RyQ9{*zg26!KkHRYtgmYH zO-OYWkZ;VKKId>PviTRyFF6Kw^P_w!rn(s_)|mA-l%PNNOV|24V?DFUuA|mt=?fX$ zFyEd@Sx1&Nf`<(lWF@k?4*-M^QwVjVVM^b|$;FA7NaApHMoS(pYC!cVUKT)4-=aERp8crl-N zX{eki#gLM1hXm|#vjZ2hR&RyTt6?#Gd6KGi8I0p~vzCXYl1zfEnXlUzR<*w%~U zD1E-DS~XmuI)3b4eJ+(YKNyvzCOfi?dj|t|T5gz?+wirdXBE2B+z1@)4@FJfv-hI} zJJDU)=a9eZw)-M4!b3P=`9kQKB&SE@qc&)Q)+wYPIN;e$dVC$VD zVBOEQrnUX}()`$&J%@e;ynEODSH}X|v(Zl^mlswOE>&No=ZRG!I4~dbs|r83u{t6|EUfe#leiDr=902C4Tu-Ymd;1Y(SM-*c zq;+-D?cWe0_LGdG=Cxake@_9y9{nsX(+BKW|8(8GGA=TBkY?IXnC5eq!&Nzx)WfZ7 zL_-pmC+SMEM;u+pqm31J`_*e=Wi#G#w$AOkSV6+J(d(lt^kZ6kO_IG9p%)7LSdlv) z7REg|UYhE&vL9W%Q1z-dh^_=)q>Y7c(V1}KEvrQ^oz!O4`({rDo&nt64u4~K#P#8K zvb0DXCeD%|7Opq0{R}QJF_8$Nc8&ebY@?LDbicP} z&OTptSL)pSPrBPKjA21}1nS6ln?k<)%esT1E4wqW4^;eApb#tSha;!bDcn+qohpv!hISQh}+i06?XL<(r!iHQz z@f}M)m;7PFb)tSOjAkSIwsL1n4ZM2A>DQ{aA8SfK;*1saMkq}B7PBFfOBE%1IWKEW z#qiT`?YaxQJszB;27~ag8vO&mr6n7IW>!ot{Nql2f#8T?tX1$GT9^2$Li&or4k8eU zy`Co;ZDv??J7#>QKs%(cW;**H>IRH;g@e%KMo<%UGoH;CBB&mEBlrcEO)>OhTgLqT zw3@nhlE8(Fga`3Sh@$C`h6D=dQ~XkAZ4UfaL;xC&9o=|gnLvUpZs#kZ_QV&a{Q9j^ z*Z%ya1F-Nri_))`gYU68@@D6Y<%Yf=lX%MM*v5mxN*kWOXWWT7VLLuF2$Z$tfQgsk zeUt?B7?Y*$1ew}M(ut)?Km+thB23(xJz<*jJKP_hKL~6F9DHd~+$99<0)P{cwWm(i z#2wimvCq9(Fwp~iLl1Hp9g4LX!A6$63 zLiL>CdG!sO^%GzP)KtTKpnPlb{IWl$Y!grw{pjtl5EqS%D6F^k6VoN=0EEc+o;QSI zslfy@mlXTK)a+bA<$VBMU8rn{O-R0WMrt?Vay|N9O1^S;1GQHT)r-DUGX?Xb-5;sK zeOtTNxbu)|4GkT{rNo%BOybFdJc`X0F+BE5tAzl$9(gH}SvJe&GW(^+Lks@g1PvS9 zARBLvps#bL-@S9bEUqP?krkp#+vZe=$Uw=?+-jZpIx6+gUBl$ZAr3k`k9>oD2LJSR zTkV1G-02*FM9-AeJYXGbZgW*h8**%RO4VE52ya7M9)hn>5smSoG}hA&(PD_%6Thi! zh@7DNvgPiQ=-L7O3R#+lysTbN@%3nNHZ~DG{DN9j?+dr62}K(JMHY$lNjTZxdW8(h zU^F|fW3(^|uPRdt(@dMHzRYRlarzVe6kK0*l}bYJ_?V1^)H7g-V^8=j^)%HiEtTc@ zfj~l)c#8rc`6hEmve57Ed8h=Vjt1MW$8+9VLoY1V&wQsjd|b8fp06O+-A#4B@cny< zGmgpoE(a6Wy7c$-s2AhSXQAJ=)W8%amAYS86PNYzzQwz)Cd0GKbV4T>4o-ttmAkTN zhWB?Soh!AtEiPQXZ?@QcB^y{*;?V?b8cFys(?uV(RSC^FdZ#1iW~Fjprdm5*$oBdA z0q?k@)l3e6(GuW9B^Wrdn%m`z--w65t^khqa^U_lKkpT}H^tIyovGKq)eDr3)xFZ5 zgEh&%l1`aW8}iD}f=mV>*%}WPe0=8lts6ZA$qq*WI^1j1{KHF2OXrt)cWkSm6;|=f zA$TQs2-KV1w!lbG;)n;Vr+M5sgOqD)S}yB!k;bf+J1!mpe+p7E7(e^o`_U4`W~uMw z8dj6Vp3G!NMNcBdv+11T8KQ9H_?};P@_l&2fjSD+eTJPc*D(!#g;MBL)2s3pbo@ad z5c4dPHPI(|h4A~Q?!#41HOLH6H~1c2_$Tzq8-WM*Nm%il4d$MNV4TYeMHcPFX6geL zY+<$}E%4oT0LR1#JT?$@F=?Md!(@U3$JPy%*sW~83X~R#<>OfY33hgZnn3C>+7!1o z>6&p%tb*YE@6A&KewTV*^o5pL?$YCMOU!5amtNnnt=I1RwpSW8Sy(9bu&V zgw=(VNmX`uY1Vfi8CD=V6E)<#KQqv?nBTaBWG5Rs(X5|Gl#j(wzaJ4uaqtasSpX(8 zKu+Hb3+|aI=d#wHiykU+TN{7nylT{Oo~?PuGwn&T@khi3OGw#5MfGD=N`MgNwc(ME z|9Y{Y&odWow$Jm$J~^DqiJrfDO^A5P~A$V`{-Bl-9Lp%A$P{Y4*P=OU`Jq8k4-rBrDj0LqgL@E4>dJ~ zEF;h5yfftmh3e0SuMZX&+ehhOzO^SS)k(5-5*TJ&GaIQXj-0e)Xl1(F_473ybT@bJ z)x*!gpZSIJT6|l{PbwOJiXi5`P)uug38(8}?-A^e6cX`h$nk$kteii4b;CbBXGfv62LO#!CldXimgeOqZp5PWZ~J+Dzgqr zV#W;g>4qZ)AYb%)#}j=b@mcQqW??AYK$y%2n04^B-}d7!Sfk8jNi$y@ral5DiZr_OZbcSK&vzBnUCpy6qtZQfn1eBlZG zC10QHF7sXCNp-*unePT{Ly=JNdFyjs(^n zB|(YNd!z2mmciRo@|~0$8|mm!FP{vP)$^hlNGDX@@endI*cd2#$L0b~Q@6qx=$ z?o#VK;ni{S>d{G-O!?t?@tEb{0geZNt*Z1*?aM5z>rd|KodNnZ)BQx6N*_al!V>?Z^5z0cO_V>v-$Bp`ti<_mVZRwDn>ApRZfxPpsa z3iH6dCm(n)z3Vi|r_LHU8#W$jN&)Ck{(qi1 zY8hZ?XfyikL}1`jn}{eMPw(9g0)DUO43Rhy&gz#L!SwHp=02oGp)*3Ju1B&^uU16i z^`nDywFmn!>BE@-Ix|+Erujtqi#}E*6Cy;T^4wu;Ch8k!AV86cMEAHTZ5_JzGL%xw_07oMd;E zWAS!f23`N0oOS)pkMJ2n7|#XH`u!?1V@eKD&?D0-*|^UPyv8QLIy7u9-2eJoy`c-K z+1_$j`x@G}71CcC!o9m(>2Z*$kX9?_9Rm z>mz+f&GC}l8{G5mN=Gq5UB+49Jpo8k*LxIs*kdJvIu}wfS@EX8F=SooA;(jvSzmuI zrBep!go|nO14{{XMewult> z>|@Tn;1n+H^Jr)42{%-nEw1XwP!Uu39F*}J)N z+lV~waeHq(DMy&@Ho_0R_edFh?$0o$z`03g@F1XQMnHd?=ab306%x zck#=$r>>JSfef*|^@H19SQ&+IfOuYWSoAoC^X{n{551{g@Q^9XPd!0f-}ZxA)#eJA zTWbqy+dP~iI`it=|I6@LF|y$;f6gZXhQC|jc)*5= z3k=&tSRrcYkYANuHW@Wgi{k;0a~%Eej_VEHOQ_*53$vxYu`Z|h+IL0pTEhI&brI#7 z%!YFBq1RaMq4u>uVe@k)>c7(L?9Sh^^#(>IfR$#>UZ`X zlvlUaXk)76hkM+Pz^>CW+3aVEOF?A!qDsi&dU4mMTfQ!7z&i#?C>Cl+#11J5({kDW;X(_RnUS6+C$3fY z)C8>`d3bfG=Fv3m^TAqeU8RHH?RP&|1#Cjc%v$H2un$8JW7n z(lS9w01{ATqP&m4zW%$S4mwu8T&gq$x8F?|SNl8FUfUw>h?ljgn6%(X*uIinkuLGg z4!LES%VfQg!Yo-B`;nXWjhIapGwND#?M@265Zw#$;orB`hi`IlJ^aP@R8r(>Fkcw_ zo18GK)fDqE$&%A?(M*>!LK%b77BI(>zUqIgGroUtm=07UI&o%sDK6|q0ZP-F#8|HP z6^wD>_u=uYS2D~i`sgLhNcuC)gKh87wT4#bk1jU3x6&4~ZD`(BRX_~;o~|f+$)=}Z z`VIFv42-iFGh2v=VIN=m(Rwy-lCrt>f_QH19gPGFlTRiF@5D^e3)-_cCu@|C&&spp zHl7%U->(m7pp^5h6BRGRl|AYo)c^YIc{2gM*%4M|%Ue($o@?9;KONCy_6KaKZ+Vy? ze+TwjK{o5Jq}qdf;qYQ5DQa3oLb^)5%&M+QyLS&T;@JVE*U;}6_@o=F3_sQZnrlIuh_josm!J~>|riI?6{^2m+Trtd;M^iTaU z8?FIi4o**Bl`l=t*13w8}ZZMTm@uPSr6neXS_zKC)hvi7&yt2_FD z9gj7xzGeE?I7a?A(Vme0C$A$8tJ=Cv^q~R*VxN9e?dAViU-Dd#zsfa5O&^Ld{VGR>Q&@fH zRLNJVS&-Ls-l^5|eK9}!F&Ql1pLqY{^mw*g1aK9wMdeNUP>0yWN zr`wzd-TKdtTpMwpu1nuxZ%5e{hh$te>xGFsTK{QwdtlB7=BHxe9!+x-i9I6~Cgkn~ zSmZ(iJ~X?w&f5E4zK4F+h{Bdyr}y^)Fd3hV!29FW!=AXFoP8r3J1ifer+KyW@Y$t6 zjI&JLUoSh@w}keN=bK4vxT8!d7J))Y3p7NVa#Ugukv5iolOcWoT>kPdm~o%Fv|`7&q0!~EgN&_)wnBvn+Wa# zC8{I)2cBfb(or02@SRkEnGk8rYY=Uze@LJAd*mnIJKIF%4BuyIv|&;atQ$smUKD&G z^mOGqjkFtmwHtaUtgJq4$yChR8(;QhrtGj-n-y!)Iogpf?HMv>enEb$gO_Igd>dDH z{HD+S!*cn;G2HI(s5(ww@Es5XqskPT3P_WS1+kY_&AAbN>!*fC+|9)3A-Yqu^#cd= zS?%w{?XfIAqz0Z-Jf}Na4sN#1tL-TCe~ft*+I=ys<79sAPRUDKT-U+vFs6`u_o(#5 zeX?C$HOa}0Kba7dqG?hZf&1t@Ot~YcQ%NgEyk>$h+ca9N;VBrC5xM(DfvJ?!#q7~h z!MaW6KZS@{1YEYepnjfhTAyz|!6o7UFu8%=HY%)zvO?>!==Er%JTX&d$Qe>*`_0diRW9K~cTG5|jL*ksQ1#Yp>J6M;r=f@|4PY5p^ef3u$prA68iap`@ zib=;VVOH*Oh{6aFyKCn7pSf0;`$#Kbd$~G&j3$RAFXIol&p?S2Y;qU>V`!?)HT5Ul zJ4#~VZ0%TK=bql0qbH}0VBo@{@R#t<-j!>F33m$YBMu!Kd#E(KPQ`fknCt4#5=cwE zy!9UU_zy?xC_9NN_#>hLv#9UNBetOL%nEg;ZMKzNo3cREs>Cy31Qh?ORDNRKO}-3gV-d4<+Oj;>5tbu z_+m=au9kHr3wrR)jF1Ce9J{njWSoe&WoY&%q6S|4YJ1k*a{XAVVvdNxnpM5XA#|Fb zDSo&)v{!Vipj<<^kRB}Ff8nZ;+F0V3UtZnIIJDH$etj&HAyn5~m}#;6e{6rX(+lW+ z8aXg$XQz@eLqEa-MtL8u$6I|RFK5dR9@Keob|c+!_X&Cvg46e~yWO^Dv)^7=4uqgd zcWyxRW;=0jH#+qWpwy+ml3~@#lxX6f6pd6vhTNGO*7##MfPAqH`MJ6@`VN@bBz)>- zCEPMUa)N8VGa$SCqS!{o6S+sUX_I3$O@^=b24}B?DmVI!9s533gGDXTW0+F0#Gs_&YnIFJf;FRWZ49d1EkykQ`(hB zC7E#VnKLt%Q)cC~7$(zLn&py~;Fe5TTAA9enL%dmAQ5V62sO@BroxovMoN=gnqs(X zAX65YxNoQ!RBwn%ii(J!zz_Xq`p)D~f|Nm@hF+#&?eS^8S`@h@*u2a(+-w_=OFf57@<>Lf~Ak zF&B4`V8uDn%Uav1H~aEUN~E`=H}K-}FW%-6*|Esf`Qe>QcTh-&tjlD$?ck@e-`E{x z8-Vw)7X0eTlde9Fz(rbm;6TW`jukGQzxhr)$a(%2Q%}|2O`42Y#sF#+qa-@IQ=n`B zpAU(h7!~j6?%qKqI5oaax}~0u#qxf>VYqCTH`7`r7v&jf#Yb4aK!LOY=`S2V9AnbU z7<5U^D-N!xc=0~BJ%09+eP@;<5nHNbqTcCavoqsjr^W(8=*&`E!9bzN-)C_QB)(U5;9FB21Kkh#&nNtLvDxc$DhhpJ zM!%n`vzXfuN%{@yyYH7V#S`8y^Og(+x+rmJ_;k;sq%4h z7KIF)U_FTHPwT@!UhT`VjN(=I{F6X#;fJ-`CKLBl2LZ}sj<#+3fjyf$Rp-{*Qs8WhjS* zF}gxOdA0VEMowG*A?(GiQ_#FgNp<5<#*}gRE!pGRRWo}Q97E~)cFV=k{plma&B(Wo zPi%a!$L1t{!@eV)9Ve>-P6-~=&PWX3*j5Pczj?loSeX6M@$7j+w(p`i@GiiKz2R7G zGs;Y-TMapkf!QJ9caXYJa@Kgl;Y<%+{JY<6w!vJrl~qovm~!Qt1N(Xd;^aqzTQ@*l zJX>aVeQ)KnI(PL>3GOI7V{HoiV5;!EMd#IF(xF3~YFgXMpPv0iFaZj5z2K@pSLR;& zScVF^g>}gNvG_e~se|BSeWf^S?Zq&?7r~+Hn$y;noqSrO+c<7+f+)SR?H%XUO~&`q zg5y&k>8s_|a+%*0bY8eNP&QrnJh{OJF2pmQep;*LZ8cy#!xL*cWbs{wtht)Cpb@gJ#USgwCdRx^60oH;;1;Uh_|tC#e_GEBFz zcNYF7Bqhc)9%E88!URnyv|J<6j>@QIF$*YI?%4%g6z^;TniUf0uvA;GE)(_R?uxf- zxN`UP&}c8c4^#7+sx#!J+9>m?w7te-m)(DuMWp@wLeKGBnhY=%|86C z*tRBe)BlQO;m1>b?tU>B@oUelUv&B4sXc4#y`}*(@%jHL^J&+;ye0zn|MOtcOYLL) zZ6%cNyCO}C*NPpjkk?&q{rFHd0f)ao=*}8uavY8C^1iRM8`s>d|XPJYz zOa;ukoVkOjZ4N_dxEwJ-!?Z5f0Ge(+Th#)YpsPyw3$KBWGmS);&dkg88m}PrZdz_$ zg})lgiPPgMFth`B&o51@WC4~PWR-`59-=A1b?$QwtUH?ag-}!hE@n;-H`~u|p}o77 z`Y^8ncB*g5XuO>WWuKUY;_0 zbWwydL{|(R=W+}*Q5I(D2VPj7AS-Zh)Iw|)Pifq&)1R2@{4li$M%;fte1g)e5~*+Z zo3L-JVhW2cSpqqGh!;lk4wpA(z!n$CLpy_vi+58$)zfTx(L zo{@7AY9%1P&N1LFN(2OjSbQBF`d?S%ug@5$>jxDmbulh1GM7HxO#YK@ZUo&X%ltgd z{4gzpP!)E&;sdjiWMzc!7T$VxeKrq@+`XIKtn;ONh1h=P+7_xL-R!Obsy z_J)(=(rJ4OX~3%nOxuL2W;&3(S7eDirJ0bqXOrqMs`m&*^|p_j8(9A!-H1Ktjs>!z zQ=go0b_(%^SvN53l@Vw3`Z}p;zR?O0Auiz>5xSwceZUlL%Wen)vfA0#SF^=|3DaB5 zYmL%UFHDNMT{INvt%95a$}qdm#)4c(gCAs$AM6?O7h)q`dVuF+8@oy-Hj&EMm9)2d zWBEooAs60Y`!UUK7S$j`6D=d#GBV5uc_^sUEy3%tD?W!^l5|W(gO{Zqyb)zZ(eI@U z$?Re)fefb9r;V8?!gij1TA|w{@l~ss?_OTfh?r`T7&fC{uNs4mX=ddWT|3CpQL5`R zK%~Y37Go+Z#x*8w8vi~D(&pz)YtcE^J%VTe`8{jAV#L&V#7fYmQhlC1eAI}EkWB!Vy#Yl}nHTl)wkE@|^My>Hhq~w`8i=8vLyxpn50iXvFB~99 z?UYBa7~es{yA^eqvIREzi9ZQB-#tAvas^ch$-O{{Ds1>vShUDkM5sq%GF(`J*B&o4 z4y+x-TDo(0%-IrMl?Q~ec|Lffb-nu!wrw1~&cL9;pu{AUDXjg7CPOdGuD#mgVn<*v zyTJMkWc*h!S9)o%Zsc0&*2##c3oSA`HwZPtJE?`s*F1totA8O|SNx?E5eO=_ptAk7 zg93&Qwid+#(8$+U83N0odkt}Ut@Bqdi_Omswkr3ccmCnhQrHRR!G_LlMGrp|rPjkx zZMFBk}Vz75rP*XLHfU`gzM+b$^BF|8uH#GebIwMU7YbChc ziBgC;mXR{((DyAE(CfmL9%veK3ve!kZk8(Zt!u|yM6SgB@h+uTZxmkl2em{`Agerf zE&yUdtTg_^cSrt3t&u1u8^oobFM_JCxauQyo~HT?K5m5=$Zm(jtp-mVmUYFc67dbl znV&4smxBpxacr8+Tn^imTwg-B;($1qJg3NC*^YMAZ9}nE@FJ91AbiNb<1ZS9ke+%{ zMY!nJ(iM$KyUvKbWaJM=Zx`dQ3g%<=-b=DA^YJAsjLWM%G$Nbng;H64T~f~IJ@Lu8 zhk<9{1mCqB%*BS|D4=1pnS7hIPd#3T{_R6__MU*AXeTq!F;3y}ftx4EeihS?`VF9A zovc&nMEBETaL>@^5>#mQ_$uHV@1wr~VwRfHGP4f9-T)O7cA=N{pFCtjb`)j zwAro(3D-=pKhgh9OT@kUQYUIqPkF`BI}kX)`uHA79Yd>rkERV$smUO2eA9j2y@V9D zLiZBCbtKi7KmWNXT^eIDk{Y3eM&`F@#st1=QhkV6K_IM86K!bj&c!h0DTyB;u_lHI z_5lG=fa7mNse!-BjynAfchKf*unK`N;5BOxnSU3V=|dHGOqic^Faw?8={!IhTas-9 zdUguxBGDFM@gV2>=QNwEKK3AMPa{x)x~M|o+`A+YZYl|T0^!ARV_^0$)M2I4fC3+I z1@=Z>)qY}^{>r*Cf$A1=zDVoS#GzJ7Y);v3mI%N|ZC;x|sqPc6o1Lhd772aMto$pW zCzHaofbJageEHdVU=)amnNA33^#Y35Xy~r+J9dR^<3<#&c zxgi`?PuVF>_im}d_C5)6`79|QRYIve3DFDsYz`h0zD_Z`(|7u_vKk~VYPO2*r zj075>YevFB1ykl1+^S8YPl9HMpJ6I8UHPe&a76UUc*))yjrV{}oa2ElL%)BExswEI z-;94Toxx?|Yti(t9Bqvb(qBWm3^)q*jp)53g}bgp&Ax3r&6wUPtVnH(PP5}JCQE{e zpk&4K?fWV)9-?|RF7XVv1C&Lx8r=Q^nP_`%mo@pVzxAVHROVh+5Z41y=fYuC&te>? z<$Xb!IM+vGsfna9pOVmU)mXq_T}=&dYxy|1HaVBIY2ob1?T?U778bSGMWo>-l(ANX z>brmNPd`=Y^l4M2r8kY}oD>$nYh#M`Plp0Swrf}wuQtuG>C#(dEX?h2(LWbv)QGJlw`uDii>x?OrdB{eqgp>qVZk;@Ida)>D(Qnx}26wzfp(`L$$8i-%agZ(GpH(*LN&{NVOwY zb8qRGHuhP?kZiSl-B!u86aKYLgijj!g!X=NHb*_FKX%)zoRBhkdi(54B=;0}%Zk%z zQH`GS8H5+gpw)IwaEF_DHff!9zRQU_d)d&v?VP^|o#z(hTDAD|x2T8h{Tl%3x^cQ3 zm-0GV5TP}Gec&cHeuRpHKrl@}`5>WprG>+qP zphUa4jkQZ|!jUm+xcH)x389=2r*iLpUD6d~)nc0;QA|-Y2OyMM#&W=ffou0f0}UY| zi5EX_ev8&}%juUWKSVAXJ5=*anWF9wzl4uXw+aw?T3(eU_T_D_ zh)c6QBP!W&5VD_J)1z+|Jk}x#G+(%>c=3RQ&U@Tp*>AqlY3$ks#T@<_n@wdJ zel9WH%(v1EZpd#Yde@GWYv<8K6KT$IKjzZuW?HF9_5CQNSoNyt$X2!kcxmA3pKvN& espg0^`uZD21o_V|&3&W&96juHhdC-NjjG(HW`LE zI8AO3WF((EgH~#m9Z>hXeFbsd;)91{TN^*zCzqcUnfloE(mVNVfy9~T%7tI5Jw&pU z9&ub0kP6FgKiNDv_Bfe_onT-m%sv;T&M^vjk>hP0 zv0!(eS;2c}W81*ZZ+&5UcX(liH2dTzhV)>1U-)gJfXL#sE{uJDjhW9xe3bfhcf#&3 zQ}XV=EEWob>bSj>HQ0=zk+J}H66UtKxxdGB&8{9CQ6+$vs+oWt_g5;CjI=s&KgJwS zpBx|Q^jN}mrV9ub1xf?w!SjFYut)kiyFRCxmYly zDq6Ad9fO$;op^V=v1TzyzS}Pva-vXr^lo3GFR#=f4T`^K)K79e-YsnI*YaeFi{-)8 zLIrdbZT^}rB5=?x)@aq~s>!}5aJr}KY3NA;!h<+Syp!5dcKBgE`}6WICIY6Jw(r=Xrf192l1p*lv3pl;Eb4N8{KPPFY?*!N z2Z=h7L-}7v_gqVLPI@qoG}5gV7l0HUMQpNlX2n*gIASjh58n-foV%pz&tE-bg7GxF zySXP0C3$6oCpqTR3aw?#uZ|8K*$lf!Ze<-k4`Wei4ILv-r7Uy7Si&?m#S9363kOYo z#k%J!iJZ_m#21p>k#B5ToMp|zJr*t`J*LvvUD~QDYoAHK6~7xloHUnZvJ;h3c|LY> zWD9{Y-Q<9E6iXX^7snss*sN~9-%bde&0~Uk*Pc>u`^_n4y+aU4a3eCdtQdR($&s6{ z$d_#QcPui%3N{{>1g_yj{0Ra@ntLTR4){3)yP|`Hb46>C zc;Ro74m~(i9QYpWDE6$al8jx2ez5wn|wFOuTTNfSLy`cl%2@ck)c`Y|ZyZn#}yArIPr!5w*TYVUPm>HpnU5xBZ z{;>ox4b1FdS>WRRw-pM-$Q3B2bsOD*nIpT@)!Axd-X!qe4 z|Gc`(-cDr#ZS13r4E8bI4{N%lFRXo3_h6)_+7m^+xv+eDMHtPs9dHrtKc3V&IvN~U zoSs-cggYI1p|)=(cjs%!Ax-Fes8eX1v3p4iv8d4j7sP0TdRCcvnZ4=Ubb{|n&h8be zq3!o>TXD8EY9P?t-V=%50ZHv+|CCZn7md#l5u3K1kKd;O)sC0-b}~OJyrJk$JsVJ!1W%NL7?@*?R~c2)gP&Iqlr?brD!d z*DmLT2n!=OAIrjSJo7MkwNG_hZ2GwvTY~t4;dr6@^u4v1wU>@W)2q*Po@^AY_%A#0 z(sL%GOW!2Lb2mVv@!srg9!F~VPA=rhgwTaTAWhDm)Bf^j^CbJlEQ4v^Y7cP7f{p?U z11aYf9dh@cVP2Nj_=H_C_8t-vj%**!yciv7_6U*h)?I*#^hhz&-uYC2yNSSVyQRXZ z&{pDH0%W_3KGifm`Pr*?v%7;ZNV%DfnV2ok!zPO&yi#klA*l#%^n5FcaR zoj%SZOI#s=_73cuiw{UjTaNFEOZ)k5Z+T2IQukCHx9+{$AAEi=}Ihfjbot)ZD+BiQCy}2N*DXq+UFB-#fO8vlRN2jW&U*0B2O{XLW@W_!?pHN z2>z8&dxUKxcU@mS)4f&yM9Hita52_AruQ4ZiL_$4JgA#KjS$lw7Za0;i#AP?0m#BD z_O{uy#ZcTq8R}A}9aGBE)#{LHHQW+Xni3E5Hm{EA*QW5S@B8o~Jm&*5V`?p>gt-N% zbWfQ$%`*mNuJcy%!gSL1wgsKU*rv;_orWXaG367Q^f}~2kVFfa@D4U~@x8jDXRN$osvwd+ zZH;?Bk`Bb0WMC@?!fiH~dF>qZ(!tyK;OrF#)(CZSez4Ke#z~HGK^;MGn8hfc>C~vE zu74hI$C!kwg`0KKhMSBsj@t|*$)a$=@yuR0e%eNALam!Q_57Ujab=ICYp)c%k5~8H z7_nCqk*lbb4D7&9hEU>rur=Y)r!pQsa2axV((rTJiT4dwIC?5CCXOb(K&88=Tyj3Z z&3VSSe01MNCc%i%wA&sfVbq#sMhWw$`}W~YT|mpZ1d;ac9JjY4y=Y3qXmxyG%o;RU z@|`W(B)UVdIX}8_1;4P{yyvmFF!Z*}Cfn;hiVX+Qc*=(t+>AH6#*$vtSE@&Tk;)D< z-ju;emn7bkyFxn%RTEiz%6;-!ken13|HM_$d&nN z-Grd#a+u7rYO$pE zljzWkm;*_#(Va_D`U>7GvK!6BW~ESObT<2W^)RvsZDlUS$zvRcwelmrD`a*A{mavR zLG$zKgOSC$G}Xnrp{zcKq*bmx@Px^zvxvtBkC96E4}!$vRpoOF$))`Lcnzk-2PvQG zxK9XJ`Gie-{{vo2kl+glAa zRC{~e2@wZ&36^Jm8)T_5-3K}+cbb)_1oMuiL^#%6M@X*bq4Qg+2H2(G%)s<9F%jVE zOMu>*a8AEy{brk9l+dX}V0s{s7GiKPDQZmvc}PMgbNIEtP#zLfUARZQkrBQfrSD_o z@zrtH9c(1Z!f<4)lh>A2HS!1!P99Iv-5&g=fmjAI%0c+UQ`4E+ZKv6DZiI@ zg)GrjMC2>?7n1CjQQLkU-8|?xNa~nolE4Z%m)~uNRB_)kDyskLo?2sauOVdALudn8 zV=rCjtkW<^qU8g;WTF5RZw8FfU}JB`xzVdcSvq128Y9dHvP8RsCMoisbW>%U#=jnA zHA)XVfoUkPG-xvh?D^->Bux{O!o8Pd&)G=#@%@~OM1fgm7W!kBwKz>8c{q(=8{b1Y z`s)PmZvi9X>Dv6^E8?=7HYR?@*%u7I*qF_7o|K>9+Z@EK^}Hn;*lUXxsa^C_60J|S zntWMz%b;e~WSo3>%~V87X3mO4QW*T^h=cILiU}rCtE$`i?KNTgO?1Ep4vakX9LPJ( zeS}8fQdtI=x8{J_h?>14Zb@e&eP_mI)U}b@r~2}r#u*vrAu!Gaa{m}-fkbvWp+W6p z*Dk&`0o4@A-yX|cq@Xhj_t>_fw;t1uRl4S>vN4A8%!w2EfT!e{3bDhB+u=qu<<5PJ zYMGy23T0j(=-@6-2pzKxTrN8{zD`fBGg-g@RU~S72O2~&b2hliXV#iSD9h7@SiAo(^GxE$JbNx$>&awFDY(*3l@RLU=;;sj zozf}frrc%W^l*4pc4XGVsqc4_Y~Z+zRH%Y{6l3QIEcb{B=W83p`LFW*gM?>IdcIsP z>~76EXY4k!@J6XFYKMM7gUKXS{3LscO)AHFVb@}+ zmrfvgP}Wlo!r(D+zBvhFkR&g1aLWxjiYs!&+v_Z|0StsyfwS(yTE039*#!1;P9E;* z-V~(YT=!3x>ER{=9|h(!#=IO2(DO*uvplsKl5#ohI%aDb;BydpdYa^Z0@lorf{7G;RI5jiX>F03m3TU~7 zePM+JZ(i~@rBvs-6kaj$2i+iqeQFIelo6>5%+LQnGmg1a(ohH99Reomtq!;@ChHbI zyknYM?1a4|*e$%@;4gy|zYrC0MQGet;`=Y=T))iU=A70q=G^W4|NWd>RdMx3oP(GQ z5pdes;N>1?@8TqRBBoWIDqo9n*Z61-zKu4jk6KZ~9i4)BzcB@$lUuE+lbV`p^1%H|UXZdZ4B472T7zLd9KxwbbTvfnLYwCa9Yj6Ls4s1XW(!(U~*Y~xCI&d_Zt@$a_d zd(a6c=-Z(zQ*VNJ4hF`ZZSOO%7i;kQQd5*>J)dtqxwU60Tk4972qV&IWYSx12bFu{ib9WQESHRb4dRWZHL^vXZ=Q3{7E&xHmqu#c1{=NOpTqY9qdw5 zm&+t0T|Zg7^=G6rtd`WZcx>?Y#B3T~F0ZOl2DOsz->PvNS~&2#8-nhFY*Wv^@S1M0 zhC4_3i5}a5X6kQ;?`|J#$6h1`wo+6?OKqkkPGMawOeoOc5}M#$H5O;H)D&EO_h^+~ zAXp^z4IvYB#%wgD`VmO;(ARkYe(><_*D~=JRhZhmLi)&1C{M2X+~5UQlLbmKTo&}y zH=o#xf!4qjvcUUXN1AY6cKhhZij<@pxzSR0X4+NbbxM z0q0j#x!I~lUTzmVzbP^v;9}|t@t^YB<~F^2`IEt)UxMBFUCxfoxC`414aW95Z~4Pr zhu?T^l!qvYFv-yJb_`=a4*;8hrhq#0V*uD;8%q-F;K&k4wkwf38wP&qFEDPP%$11H zph}gw;{ zT4`3XrwDd!^xn#47BpSglbHtGl%VZ^a4UHoSjvVec~lwYsw05PG)b?Fb?>m2I3{jf z5_A-qpQA+JLYe8ws|ge_`Fz$ltd(J=F5BE~Tx#zH1}kQjRvJF+$f3=1oW2aTMpYQ0 zRxQ}VVw&f4o}-_;vmjOP(iRVmYJzUu0_|J%7luWzr9`=-ZFsHP#dzA4 z*XFvr*a4VF9ZJp=eC~a3{sqj{dy<~!`CAoJRrc6(FW|=5TTab7`2G3?dWYl7% zSGD(#Bg98%9L@+)nII|kM5ws@Th0OVEltT&*@+24`C?Obh~Z?~oQfD&t16;(z31cO z2YvT|+s_W5x*vwB$sswu&~yS$eM0|h3dG^gLEl=74kv=N>qyu1@B$9~-0te%6$V&Q z!9uokke!1!)dymLqY)iH4uG-GPx#8 zvdcQ}i;BG{)b__cs#E*Csd4+_^u8FCpftyU>|8zRVMVG-TboFj4C(VIs031#?74~tNh5AA{tDz!unOJxgIHqP2UZnFqaJg(U*4H+-O3JseGTc1pl z*o6g8FuGI&)Y`w9q3*>(sg!Z@IkpB*QLn-28H!|HH994PHF(b$f*CeP9!zx0OM$#f zBm*bLJ&Pi?r_OO)IMgO$qv|dsBbHua4=mvLS~$seeZ0!E=i&;nqzvo~(ZmiH3&pvP z;MpR|z>MmWBzW@hy|U?f{X*2U;sC>;yph<$7-U&Max+^Pxv<0cQj`?cg3V z@Jwnogx6Gsf|cU1=zY$#e|3o@F-6MQ@4HMUew5U*Xyoy3T)5HO`R&FatSI8c;vA4VwCdK z%{&f(nVK8Ar(T&EPt2cmpH|llZIy>z9nL~8aqWO)yFqR)kB10p4eahs60Ech6DWAm zi7>xiVlC`{jV9U!0K6oTbmP={$7^rp$&{vSYPyhDb353Z8(3+`Le~S$@s@2JCwSF| zv!?R}*w!wH@1ml%ZKb>&jcdb(Q^u2mtFP^7hUk1DgIQ8NV7N7*KIY28gL;3IepzWs zSm10>3!e;PhTQ6R@pMUq^W%4uz)hNBi*U&NBY|rtkB1A7ld5^-!*+a%?K28dxiec7q63IE3NL zeU?4hMLZAaC-9;Iq@neUQd_#{&=u*xfY_%1yVo1K(XgXqj+c9uz zG=*a2-8)(N2lIJ47qxt=uJrBl^goENz))5q-1y9X zI+i=~1!$&Uv*z{CvX+wM3iK2SbeHjp7>U9UMivrN)kF3R5PH1e8@2BdGtB6nYGlHD z5}He+4@a=mx-dW5@Jr;AOC(M1F}#8m*=Lq+rlqAaEXos`S&ku zcx#u%P=W6hZSnhRgZvIWr<#gWAZIPYBZw}4|4r>`7ctzbpr>oz9 zM2i>P2%COzG7vP&rp2CyoD$(RJ#wwuIiDMu{G?Jyx$JH*UToxh-&$x6o`Ned;7Qv_ zN3D6EgK*)PZnGYy-OoW38Kxr1&S(ztGQ{_BFDYXXA8w_mRP?p$P;?^u`a=AxZ#@O~ znXyCprKE_QKQEJ>T*Ia9c7CyFZu%c=d8i%+;0y&fCxkbI;i^F4ltlN`kXxbdLeX6= z%(1h#@jTHTv@D1+V*V?X*Wy5_9eMnNRX3w$VU4$<&Q$=5kc0wAR zCaF6x@bd6&g4MAkSv3Bx(y&F$Zc+_>6~W47I!9K>@>%gB$%YXn2XE%}Ej+DssUeK* zl)p$jX-~q!h*w*LdcRinUv@#QRt9CdPjs(6Wplr7T_Zmmuldi20WNvx9v9N2h1=H@ zBzrNDskY0)mA89L_|mjPA_C^%sy6|5!4q{g5<`?f9d@$N8EUY8CnCIbw7kOxzSE^e zI6~iQWk&`eioiwyQQR!&icknkrztK}h?yQ1;E~(H(+=-4xLFU|bSJfYqp=m(=1pgI zcZU2}|IzZ}8!9;FN1pI3`i%U1Dw6@yi@kZ@nhYoeYVr0jZQ38_K*usgtYPzumjYYv z-p-SS9_-GJ3t4y10~cFYXbX87ziC1u9<+5_A97QvI|YOv`@BN__8^MR^bBpS>(EsA z9#!&>6Y4pgRNp;*?4~o)-tCf!NRCWTpqp{?f<_R=LHElFCa&-50gL`F|2LH0k#^aQ zIy*Cwn;Vs6t*JXvOyEmdmSqu!u4TkD$wy!P7u6-cTCbH$&dxU;DnGb}Zfg-UE~{HA9zQ~B%PJdC2Km#a04~hNeW^zvE|$L%_V+iQ!Psw|d`R!8vH5BO zP@#gLn(Oq+<`{l@M8%*`(=4l~HSKh$b|ZJM3#C<0Qsf+SV=eTlURn+F2B*ws?T2n} z2u;B*ted;HM2t(r;hN$Q^s%^-2{LfxW9c#?2>y(Own7}RZIi#>IJV)z@_ImozZJsM z`jgpnH~yK~zqutK|L@E`2C;qB9f1nEC?ywejKZW>7W!lfVbX#xqFw(H%#h2FY)}kw zI^G=nwHv$YTe+c_k^n6qKErU*^o$$a6{+}bbw>_zQy7`D<&4$QKW?z*X1QywmmHa&?*3r`7BA`T){Xs7g-XZ4X;!0t_|GG#ep9xSO+X|^h745ZT2E!=HD$mR-^z%b z`ltHb^y|}@@<(yC1^xyW+V#6n!Gg6tUTLt|%zg%4SvhpshG3Swevl3`W1`CYn^nu{ zA?|1cpau6Aoa0OSBAkFxG3w|blB`z?r!0owAMTcfnQB4!q%x&3p`Gb+%-;jjHB0h{ zc~FB}NZBn~!7iDl+>X0~iRU2%MUv95wH`!Ax{b4*ujOd|nE%C@SyOo;>SM%!8ZMpY z2oUfAr9vEr2uUaQ+h|1tfWB`;rH*oTa8dsPSMHB8EjNk^)|)EML_gJb z>lPk0iOwt*iB9IizH4^V4}}bx6YsC@!9tp@V#%d1@$6lx&*Zo~G|?I0(v1SQjS;t~ z?Us|W*pRP34+j$@cGDi}ZQOj}iY+tpTonOH>lk)otqzjJrZe23wlz2%qoYv07ok)E zvC*M`JgzWvTjnS6=CQ6nvqb-xYM*Rhzfm7+H5hbjZd{oI#DRO%{`0C7hnW-tjWNx$ ztlvj1IC3p}03}8tA!KM$bN?|QxYHCXeJpT{D10)(L(3a<^jzuT871)~2R6eRh6Su3 zkFx>^;k0}NQq0-|d}rVq_)T1Bi}9!91WOu2ip8lHTE1FQuAHI>j!l$v(3#P2Z<~Lr z;S2Qx+;H{DMe`Swz8Q4alfm_YEw`-Q2+=p^ z7Y?NMd80**fze*mJ8>}}3YRMWFd zm6l~h@SP_gT6RZ*CS1LI3u~$fhzaZsY;6Kr*=#s*G&%xTHUGsb=KRAdW)l99>xKYdGVvOJPQJ|JJDNGXCh znXtE|mM@-p`DdQri2M`Jhs9Pc%fnSstCGyFjwYsEH`hktMvm@siCtYx>Z9iv8>M68 z*AkZk$aBS3PB@y`l7h=&yxCL!M{lAA;>}Y=H0xz%!#eb zh#v!37WLgvrlrd4Wl`qtqF{MeO+K@D0)7A5s%<~~nYr`zS?Yvn(Y7jNR1?@=J~%s% zg4qpoxwL8x!?sMGXTB%PP=Yq!)w*6$AvU@lMO&dBl!uS%AtS%`7NZN{Pi%GVvFb4v zpPH1uWOw_za`M4j)bp@v85oe1`ftqTVlF z6C7k_$r*u2M(q@9>gje=3t)T<&<27Phxbw4NQWPZDhgUa0-$m^9v7z~21(nsMT}GliciW2bjy|e(BNyozbQLJKym*f!Y4C`37$zT zb@(B|*Zd*E)7=@{zlU15VbR$svmB{~!8lxR32CVYuJt;bM&{SUNoEYC&B2YFOVo;4 zAlWs|fW|Taj(?t7*kF^tw5PitJR~|B6HdUnkQF@)&q{*Q3liRuKXKMUlb&p@n1*5+W)WZv`H*Q@>YB z7Fgj7JWrTZtRNt)x6Gn6Uw2v0ETQ^(|FKc^NXfNo^a!xXgilU*S{Z0L|08ro+4-AG z-Qbm03W)Kw>oHbjP4;Sk1g<{0_MAcJh!Y+qn+<02WmtOq44kv`f1N>A=Yy;Q+j zLUunez4=ic&I_pWx*`%kXg+qVgQ*RL6b2E*8Yng8;aW=oeV7mev|+LHCPrn(v=6N= z?=+t1IKkwoftFbD*sBSV7t2Sv3u1L+TWgV!J$wxz4Vh-T4Ib0M^P|IGy7lv>vvDjy z?6tklhLAyi=>$P;+@TsHjMcv?Q~sE#K?zYh*b**w;DN;#0t z81@|!#TfU0?*MMNcEECnm9ZzhY{17s2>WLD40lIQ$Ca^?0b#Bk^B3*>3le-Pw>VtH z&?uY)XzZUEJrHZ)!!@T5kD3p26|03Il^mVjzvh}IhW+7yb6*5dhu~6-mD_lC#hXS{ zXtTg2va8h5>ZL}onUkD(!&_h)zLFl=&7LIu?ZBsbfkPX1arSv&3*miXfXUym*fm$V zGlM)KB&tT)6I}&(^^m?fm!~Jdsz*VbmZNI>>BgU*Y81Os6kua*OdD6~BTe=zbj#g@ znPf|TX_$M)s0)%>LH3Rm-09!8DAayaDt6BQ%&Q~bD(>JOd~kDoA|ulbDq=KFXE3KG z0Xw%{xk$&|-C=^RJcSC34wr0i%*at?qq2yuHbcL#-tQ?XA&OE$t6s z*NO!9AA@2_B$p@0pN16`y^|@tSa5yAMzc;K&4}TW3Scjka+DWNK16LF-RZly5~vK= z3smR>dRj=fAUAze&`5q ziJs%RH!L1x`_8E=3wDu=_>kUFx;bm&-O1l#*jS$--aAgrHB^Rr)!e2QLMf2lyjA5o z!Ha%JL+`)mn{E_}{!1D=)@NlE)7j?oSnQy)e5pEO*D^<-bYaDR&anYgWB0PND4BuY z=gU@AVB-0Gl1h@Xs8FXzUPm;-mxBP?;ThxlsqKI}T}M1BTpz-`u{hI;$r=72(hvot zk@v8E0aV#aPqZr}uDOk!-Fid~W`HX5T16MGZ8v2nl5t0H$}H0}uF0K3j@jQJNB&E& z+1iJWe1o0DCnAuwiHmpWhk=wT)eFGBPy-FxM#?R|v851ILIZgvsUpcZ+aU&gUsWyx zGL8}QBc{`+!5QHRn-Rs+(6|h;#sZs_lfOYv4uI47W%t)6z=m?F`)niUd-jTE=)%NX z2##j=KZH4@o~GYaEMGE61L?O~g6dIvS<{N$PZR{FiUI7g7_rI@qW_Aja_bMx;ENB% z(&WcP>lyx2+`)4#ER(AV@w;l^G44@nfK?49xtXTDmno7aYi>SK{!^A4@6nI=o5KGX zf6F;23)BvHw02q2Xlih{wR_$qN)qh*V9_r zims0~-{L*h+KQvgcZg)Q|8_o~SIJuM6mz5oDDCv8F_g{`pb8`ge*rm8euEtC(+%U; zV4Q~p$M}|4aWre?wNCbC=~7*~&|B}h?eID8b#2@CaL1~FTE*Vd#?DV<^V-{gpsw7W z4<5*3-Ub<--KYiRwEo$s>I)YWWLk3NlX@90ou zC(lscQ+yPvakdD%#4b09fy*tGHrt7||t+sY@k^4;Bv z!ZePT(GLNAUSV}-@HWM)75Ngdf7s|8ae9%Sk(*xq&K91U4_{fp|?&G&gHTwe|im~_v|ptvM{C7Uv-2x5aF>!jwqc5K zh8zeV^S1d7utd99U_xRi(M_{=-s1!Y|>kO?o%O z0StCcf%tbhp}!1|Fv*Xd1)nbz{?HzNbZ;7rW)&70f(h?^{3WuO?sk}vf!+z>6U-H` z=@}A4Lk~SZ@83XDj_{dkyqYX3`f?FGnFKk&wXiMy8L^X-o}_}$(bOkEu1a$y{rY!-^zBadvK1CfrP3L4KR_&q3zf(b;IE#_t~J5 z$PoudF{}~Ly_D*U6>#=enC9Al=m>NfO!!&<3JRDp``0&}aSCZ(|3yehyZzG!NZEeq zMma)oqZu40*6YF-!JTyM9-5GNQ{YbC<^iJ=D7-{cI=RZkM3r$Ukb}GV7h=K>1fYTJ z`0`IR0V$#Solpkk;GN^E+L3|{b>ef=r<8Bd!DHSh0{&jV$y~`rix92?=WCH@Eo8a} zcWn-0#}b?DJOpxY!xv5efB;#3<&-dMm<^_K$Y#w%Z!jy|4HpPNT+btV(2_uBYMcni zm0GRCY6&0eM+aPN&QjetuHiUzUU`h%r>ejF)ee#)m-b|*k(`au>?}*_4N}P z#o8Nh+q8+v0{W6&qbrX1sb`E5zZTvN^@BDIAz?SfRUT(cQ5G0Hhe>hM%bT`dW}vPS z0*I9fTw~$!bKA(f_t!Ha=tTLp2@H!HmWQ;D5YLjQmf9fhCTQn8@Vjn>5p-(84-g%F(Y$N)r1`r*W;@wAc{_mjiOJY zBSaZ}EPsRtTANe{fbamE{p)Yl%-_}gPXr`N^ppGD7Dd}tK;~|$Da6TZ!uM4^X}il% zbicawg%x!ZOA67UVbAA~5=@Ob|0ZULUl46wl-D`k3po!_{cXzYQn|g$fHDblzOtzY znXQqpD}D|8P4XAHUCKRh(UTpBIoKP%xg6%1JsbZ|@Ayo3(G zcD(Xf=6DibMe{#}%WVZxV2fcysP$Swfo1bfQxTVcq68K5QTt%ea1;%3YPpbM4-+~fY{w}?I5#@G~B6d9`R>yxI-fs)h&5F*P_KZ10Q!s>6dCUP34 zKQ#$iVao5xDHO0gopo*Bv>!#VuOwfx{s9nF{g*;176>fCh8!aQAszSz&jTAnIPyxe z>?iEgN?5ex{k6Gp6O$%jdRJ4eT3L8`I+tY3+^IChy2tROuXsnyjXpjmOuf;v=jmeh zY#8-PsS-D;`rGr3=C6{r>UM3(#Y7oD6bK*}NaO_M0vqlx^OeTTzR$bHKmX9=jheCz z<%8gblmx79`$-@M^~ksAK|7dk(#iwK`;WY6#Va|<@wODZv+}P3M3(v^jx=7=Sy(th z&W>%B4roT)3x|S{__|B=Va2&(1GTol|o8}-xbIR`lR{>PBH1M9Pvmy!e z)Vs7vVRpFUwOaFaP(Fi;Hi^~?i-8@;MeN~1{xBH08(m&3G?j7&g`eTZe3VjKTpkwk zEM8b?#RFpYN5&+vCWPx-{W1vhCM=n!Q<^5dwnyKcO+6sO#NNrcdnc9W)nO}Xp3(JXhW#VZgnA$7f}goVecfaVI|EaZ17 z#Nmrx?*;$~ElHG9(h{W-AoKqX5{wh-Pm{8fng2_M5dB5lAi^U%{Ye~2EZlsV(A{yn zHXP4o%8$S*7!py^(O*>5)qZ*!urUFXY`J9WB`G%`Oj?k*^x(m_?}XX<&xjO7|LB|z zvPHy>$@}_aFAK(>uta5B%veqO4px&2H%g!jRlbhNCg|KMLc~aA zfZmd!2uQ$m`DJAmWJ^)1CxC!ZHPQ>m6}6d6@;V&P;o3oeuTQK87FyXMf*hwIl?>_- z&`5=|cyCe^Q#BXzXf^=bM$@HoW%CDOhS7?6adFil&|PMzV+(8Fy%AVtz`5Np6UVjYRibBHLO$Cc{DxWvIFr6T)?-_-O7z$ z?dKrjKXUgA_!D&~b1`y`scLbsHRgr5bhD62azI>Ay_ZraGvTho>XP1_+y5cVe||11 zB+j?5fVVspLBHSyjU##cP~2%Mb-y2)Wq6d-^=^G^ zqwVv#R{?99NFXNJ-Z!v9_H;L79PIsbz}pm75eB116F=>nn}pb!wtAto*u#_kn>Hb^gBL+5)%Ktx zUuTVPyZN;DKyzt_PMPXXMsgr>JBmM2{2X_xpPkFYTL&57teSJ9;Gvl<|B?G2|CRfj z*E-I!@_k%#*PmLx&2jS9BmA-)&#g7(tU0|WN7iL%OmW^$&J^Lk{FX3r@5);M>sV72%SZ0A0w5K#Pk0Rodj_xnA ztqJqQ-uXbh_TB<16VJ_XPmJ%mx%OM7cy&9a09-(I9zR|1PfC!-GZpOAP+jPccCg|9DjgXiLfm z{k1)y1@T=`^JejQ^LzuvCqb3iF2MUDbZ%O$b`f$@Y>&ro5ZU_Pi(tjvc#e`Wg_o9h znL{>!gesT<_mGyDMAlSO&xkSE`SbJ%T(S9fMLQJnj8!wu%l_qJylm_1vCjSPT=_$z zi{_^lyCqklKCy}P>mFw`0@{vwcwK>ZK{8mV0a#zFsP25Da2*dRhsq;*nb>UD*H?fZ zjD19^xN`r&=b=>|5YxZf8pkCxyuB@Ep2rP%mpH|_J<_74ukx9;#~iI~ic~PN+aF!KhCv}pH z)Lzm2r_%68qnvX(5QxqFs2Ye;tY`w#6TCDFL5{yEo0}xtTmdCLknL~FDpV3M9p%p8 z##CA~5tejicRnzNye^1_g?Lr7$rb9(1&t61f9jsSoayIZHpVhexV7m|Uxpq5x`<)Q zKo0%98KvLHj`7+fDQW#InHc=4m}e2w4`1blnQ0w(Rqvtnr?m7$A)Q|hEWyN*ryj=v zN;$=S^y{W_H#WT06ZdE*_4VNAxxA3oQt=gl;^!m1#!l8<>ByF^^Ztv$k)=MHRTDo% z=`t?hh_|&-qFd1>2E8_1*kInXr7@a_dgsh09=x~^zG=VtAt9?2sBrt}Gy(Poet)eH zrP3>l`khO<%}zv`zZVfeuyqu%5s+ZCyIvF!^lN`Zj`jsmK{$%)ithioO&N5`gqLUU zo_SUHD(7v`=Aj6RIuDd76oKf2D=ntFu^n6Me0m+?P_*^Ul^JYUwHP_~(5)xwEeJvj zx_suy+*N*SGh_2vca*(xq^mKA{9fBnzhjXZAG9O*C%Zoja zG^_kQZy8$O7UO`q7uqOKQ_T6KDM8ElIqaMRbg80{tAYgpRX#z57Crgp0E4fWi8&FV zvgGbHaw}Q15IL%YUwtYADq6pSg(+g6#Au zNx6{9*VtVmhfx6P1%|Dq+5hU6dE*5rhf=!!$Eaztl5RLP4yMiVt&(|9z9@!kv}jL` z;gQ7Ye(i*4o6G~t#gBvp4RP|Fh{d7TD>o~HhKYHDe+DI@S*COBjA!K5b6u)v#@TFK;b%?`(C*p&?{QPUE)it{k%`>V<$FUNW7{g=kkwFkuyR3l&lB-;R+QUl|M() z;mIwPWigJkB{r~;_V+DJiE{=8FT`n*-R}kfX-BVdprR-hLp>A9=AsO-n0aubn;3El z2s}Q*X%e}hX2Qe#XEH& z>!>`n_(<_x#DzP?3!z67!WeP}vxouyu-PQquY`1s^QfZ9HSdF*dw3*cLTf55fgk-4 zL;8pg?8yFW0Ha`$V!8+}`-O{U8+U2S7Gv?V0&%GL)9w&Fx!}lRm#LfBo6b`KSLMe( ztg2e=l1S+ll{BvQNtB^$U^l2@kV~# z+6w{0>NdswHI=+vW4YRot&`i#!{7c$H_EgK`>qS&tnm?iJAK@Yg7afoRf{6CQs#`8 zKiFAo=N4e%Pyr9D;VZ0F30hxK8dLZP zF_?r~F_ylSPm}cewm|U7@#E6x+;xK(?O^o{qqp7Ch?|un>C@z^Q#g~l;&x)41Xj(O z9uzn9btOaqQRKz}&>_KhbaUHs`1qnF99xtuB08L`U;{w*mET(%-xGn>MlqUbJcmH> z_(JCFsD&qo7z~|g_Y1gVMOB2J<5H{n>PX_|6OzcmHyo%JZE> z;?ePl7V4wEt7)5;#!5VK(?`Y~8@GjNLaCG?+Fmw4M3NOA;q@Plj_QBSVyYck@R=ru z_TwD+5#G>(f{q`v!+6YlqPa2C3lKYLHKat$k!lHr@QBA#*sWeS!AoR;AMxOm#~Xz~ zp-b||q`>nBM1&(B4FNsN`EEDIcQ7TjomN=554LA{v%-F3BvCY{kd}BlIW-X#i643< z%;8;Abk~@RfHwb+Xve^3E62Ja#e@zo*1A3sh-BJP`(9;_Wz10-ttpVup{{P|e z1G}>*t4_gc?mDA!>5Y#7F7>ml5~5eW14a^QVVA`uFyM5tVP1JhAH6;(%&Ss!d%D~) z_R%n!^}NOY@)dZN{*7_fF8`eT%Lg1{;V%BpSyqMafahM4SOliuOr`g;0s+ry2#tZD zAb=xG4dgiWHCo?Cnva)(O%;H!N1+~2!Mvn(e&N)A38VJX?a+QZ6*H}XlPPOJ3`%?N+6XR5cX;RLz3w_1FdJ5Z~t9UC{({Z!^| zARxg29*@dGAzExXg|i71L!*vbpS(>+_xnT1nf95+NgGpSLDbsW#la;EDF@-OKk(3f z_FmWXtfvu+eliW>OyNA{yb?Y8nNjMtAI~zNyb7of-SP=^b^S`0gXJl(Ed@0oj8aTw z?tcB2Uhd&)-m9V5`RwlZzsEXzTKh_VwmPa^QkN7$9x;o5ia}@YRoVIy2@Q4jd9MY# zg|8$lMYC^6db7C9Svf17+say@>*bc>1ba<1!n zU60580Xyn<+4|?B{1^Z&hSy1FD>qCKK8t7H>&$LAO;W0rsG+nZC zcqTdu@7T4CA+^ksCqc;0xD4cXTqXlX5~u^_yE*8>J{vOxQG$SA<&ucZ97GAC;Qr$n z$F*qe8v)~ph`21Ix=@}@p`m8F+nPecyPPEwJy-6+W({up4v0P%&MOay=77+_8t zIc?5#cR5Gb!({>QP-Dy8($6mg_|lgzp$zV|qSpFKg`#&{XRDAqPY3dBGX08XDsTx<|a+HzvKYZstebfg5UZjj7;R$eksNF;xr_Og^9>mj0pSloDm-% znn=uQFlOkYxut_Ve{wXhPGJ+~pjkWJ3$@5A$n$$AKIQIjntxEv1J}%i1+P5p*Xt`C zLlmj_JSJ9Z4=pqpm?{L&tz>DdQiQmCVvVAoOY!Jt&b8_NEOFYsbPUB#)py0|M(cZE z^EWfRW{{{VNWkn@X>`94}q^*)%bI%c3W0E2WhF&T(53 z5R57+8oa*9a%Dpzkyo4P3bGK^Az=@BA3<7m#1_^e;n7m&;R8R7sKr{|zbupF#=AGquL1EppfTG0uLmeY@fXG2WYn&B&6%lwUZe3Y||i~EtE=nVZeSq!Ky$rl9XTkSRTzHAc?kU zRUYiU%XjB2#bAABorjRNn4W`CQb+#L7@-UV`-yO#bF)cKvvvQLvHm}FPQqXp2zE)w z4c3+X-K}ttlx;kLU%~W=v$Z3b^@2={E$nkPh7n?Evvx10cf{$9qg9cE|HX%Wwk0k z3Bgk#XY`a^UH9wPiwsPis!cqT9Jl3xRe#RBXx6MC(57h+pF+C|2~lRhT|(b4d$e}& zHXA#-#d^xLe#Fb^+o5*&!D)^1N4wTaf={S_^COMcGs|h^+_&-p6d9T(v|N4HQzQ zYAOm0zpos&P<6mr$RQKtgu0O7;D9VkM=v%n17?RNLwRM~(;1a+q4 zne5-KutJpGD`&^X9qDdsmQol%?iS#M{oie!l*A1jKZ;E36Nx$P-9jr08_OCW<%Qn@ zGb9fs9tr=Qz0>4Qp)72l^%-*(I|XRU(ASL@cKG_jva6VVhoN>pcppEdEBE<+k*4IHg77EiceH!kyV%_xuNzp%fnNu+GwktTQ_MOQ_B~rf+P2LuoL&bYYqog;!ph zeQP*~iqE8_RDO}Ow5|5&kxrh=9W8~kh0QDDGm?EKyEM0Kl+f^LS5GBi1YA154WC~A z=bq|I-eC#M=dX?>HZtMQ*A@E5(3X)(Ei}vpn+0}RyeJ^ybu0`1S4Xw(ZK1Mp+n$+~ zZ=tA_-xIV|C`<T@ zmDZ|JtX`&LjM5I&Ca@)*e01ceP^VG)H_FF^4V~N>t?@yDFFAn6r&a?y;&&>~k=hU0 zZxp4245BOWnXTm-4poGGD^xDku)4O<@5fvIB1(Mm!R(Z*!z*>AJ_*mqW|njhk3{6O zSeFq`B#z2>jL}~Uv2qM4?9AUsmD@Qux~zl{rQx9%Y6kLdI*2N1A@yF|t9R9>E=Z@1 zt<)gE>t>1VByLB^$YS>vws<9COS)r;k?sT*h{Y=y+}yo_gR?b=YW5w>y^4TINzD*! z6VoB8*1uG^^7Z&J;cvlnE%J6A8Ajj9L%%j{@q_wN{MH_x+(`96U>8Kv^2Wxyjuheh ziN!GiErS zU)ZZvQr2lprX8{@!Uv0Me6ZS7kv&oX!201tpS*K6PF<=hdSvVUl|t@2Mz*uO{B`nt zC8Red39w15pd9^wXtsFYZoQ3v?c|z5*yi*}+yW=aQX)(w5)IJjy5C`fJO5 ziPxoxOw*O?dr_>95|XCG`?3mH00kz2_sTd+t}zbowXA}l1m}vLX0Xp@Rqr#f{`{Y? zmuairMy(g=6LD6Fi7(}@6|aSq+D=hau~QRP-V-C> zTGxx=v?YC%%Ctc*u(@cKZ}Lf#{MccMH*$SDK$$4lE9g+9)yrOPw7Ed*7!dq;|5NZ2 zGF#odtp=v^9EUuFdVQTpch?n0)mDsZ5jc=Wm3tGZbEhaeLLCS4h97Gfbd53Rh{&lm zYS&7@$e4Q5EoDsHqFN1*9vv5|G);r1aaW~JJuq7TP<&K)6;97$SNuV@r4c-l5PPJO z{jlJhd`Gm~(|tD%vU-$)bzSS_^T&tS^uj}&%C#Ow!6pCy>a>zF&fi_}bIP5X>wo{iJh~Q=elEZwI_BB>a3_bdtfdy!%E6N73e`hC95-9D%tGiK%n@ED6pqib^%wb+>EETJ5I_vHfZx}_lNQ5YnE#c1fQ6GC<83t7)02;G0$EB1jY`YkWjDqw- z292{#eL?uEZU&p0vl0n}?UiB|ejBD)i#Q6WK5p>D;;5tjusG_Noj7XjK4*L!vMM`@ zcUxUF%4LxKo~(0sV1xyk^u61v?DlA5kz<(bFi_)>C+aA0@g@(Q5>)LI)akY0%b2iw zY5L*pd{!*W=GS6`BP2lX2Lj~V74@6MCyTr@$Q^wW=_v(|d0>RtG8dH5i6{TR7*)x< zStnADS&(;l44+lX@EY9eR?;QWRmW4ZP7p916bS!%7RJ-cr@})6L`f5Fhc%?x88eh^ zKh5_@C$zHH0iF2YR7qOIVwSORlNV{Ytvm50m)c2>Q=qWAq~oO@uYMFdJkPK5R9rZO zQcb%&bIoLokd8`j#M6)2Ib=UqOWAbF$nj3|eIBY&y!F~e-_A`N{`lBKCiB+eA0n~C zo=y*=GlBQxJxa;Rl_|e7dIQ1It3l7b-0>q~s^1(fz29%@(0N>gVoG`u6*7(5-2WKH!^e49e=tN(BzLpJS_Fdz=XzD#2rw zaToT=SB!7U252lXFm#r#>+t9<)|b}He$?IG^_5p_?fNP)yS_=+tGjo7UIKsJ_1XU7 zrpE624*kz}eJa20`tH4@o9@}$$&5EorwjfrjCl0edWmZrs|z4c8vZVElU|!OByQ4C z+GTqJT+xk_7&`ZQSfulQ;bU(RX)UWCw>(Zqq+s-zcovwaWlNX!UejZ5L;d~V{ZK|f zq2d#PKO7g&XzH4UXeAWFgLpNMBj0PMv^-fO11S^SEW~2x9OUjZ%G9w)HPt9p+ocy((=x1kWlG|UeQ0u1UF zy_8L4H@&nT{tLY{wYccU2i^HE_Xlmrmz(x(ppk-ZX>FFJ5 z4KVa@M$}*)#6M*^>UW@RKhgYx*n3`pPgQ{pBuLux&$iT+fh{DG1z`d~P!^f$ee7dD z4mZZwzK@s=_}-W(6oSX%#k;;CYlgZaowLnS^UATYJ_%)0j0kiaeaKNVeYSDvnZvMd z4z9rX7EKM`e6!aV(A3rz;m1}E8zdg-h>^;wAvO6aQ9gm0C0+N=i(yvE+PJFEb`~)TXl!yuzezmH z|J-@?hVBXnhozgzK>ldOC6VIg^aZufVbj4>{Cs^u%o48d#H$*URy~H}9$`U8syUo{ zRF9tHnlQb?>9tR;aH`Ukv-%`Y5|@ijc4)K!n~z-F5zsmj0J5+vjE_Kqz?XGoIIDRMRvNddO_2f_lVzt^qC%F@s!6FQ9Qa% zgX1{)qqAS8p*>u+ig|l=&OgmgVdnR8tu6Y{(i4iFv!O=bmb$6K)Tz$rnu_WDDeA?0 z^OtAa`1_n;B77yw8kX7Ic8=xTb#+-y@HN}wj=pN)@o-KF0pisCqLlyhfDQ)_;jA&lXxp^L+&Qhau?%Bka!pPR|!^ZXX ztDQuj#t7?sM+Fwtq&R^c$;^_Nxxa32kmGx|cCdkSO9LA?Nc$UKuI!cx)X%^V<@FIz zx*$i=4*4+|$mU4HjcisY0upH0Jq>^3Bk;I%}7r{6xSB;<%7Y`Fw-$Xj5mQ1^2~TEeW@G20@X0y;O+gIG1y2I z(x>{GIueI3yt8^o5|rtL1Mez?IgBpV&um_=>_rD&Y!n9$);jYX<5n??{mNW4O_wT& zcrw|)oLS7V%dTxFHjE-rpRI*6p*V#l?4upqlJAk}L420NKZ=g-!XJv!lhS#;vYHEn zgzH;oYey9jJkpDl{}N`W+)eA9v-V_qq0n$WLR}%vB5kd2F~OFZ)~J^%pwHvkYYJ^m zaRfaz-&sH4up)Wb;& zWiPI-u-D#cYr0C4z*#l&hUw}pEj`WF-)U+>++}vR|LU$DbWsOG%2mP7p~a@Lumqts zMeXF}RI95#jYSA?GBNKPt6{32fP$i~ve0GZ+0?U0){&Qhoy90iJL|oc(v1f$yx~(U zeChC>NVl{lnL4S)O+RKBrq#%qEZ? z87^wRMgL?B@ehs~(r$sJENxQxmNv8Xy?5ys;$nUKF!ueDoBet%W% zCCgX(!hCkbal_3o6sIhp%wspXHCC(G-7?@4x%s^bYqzPfEk%(NZwBMStiUAO1S1vG zTa7%eC`QCBEFHZW!7bJv;2PiZ)hFjRh`aOZU6}Q@W9PZZvw*Bvy;4W^!*sPRI)V^t zP5ysHs7=oZXanojw;0TdY!>gSo6Xza?~wEA)QHbmv#|F})vhjsZqYW>PWk}6%Cr?R zHB}@1shvl>BAWi$;tv`1_I8Yv@{bm3jEp*W%R*gx9Y!Km1MG%7&eEORAuGC`*K&Xow{DA{l$b7E9tSyyURx>`g`NR zb`CTSs!6ID4Ph2cdQTvsPL$loVY;N7G$>Z?xx4nv58&#zxxZc)`8YfO%ov+xWvusy zEGxiXO;(8eY}$p1|KJ%a-h!q&`(w6+tDpx4NVEHM&f-j9iJSnWe`2c z7on=&_{%=F7w4$>rYpM&0}7?rCX-#htzB1Z>2ZB$R+emoKyrM1B>3}3Dh0!do&@{+CZR_+3xf?aU0&-JPVuBI1GcE zY@}_Rw=^ryKLhAwzoO7Rt^U*-;Jy8&H+V>_aeG^)6X@tA@}W0~;?0E%3u20_mGg&b z#2Gh)M{Jp`neEHy#4ejR0yx(;2E8yJ0;@7N6Y9%119-V*gHARL?Fg(Je`Hu-Ye&RGLyPH*BZMpYieuuUM%MX!C(o+BF-yOa|OCg z5d5Jm8DQG%V)RNv{g*@&vsz$^cIzuP+Pmd|ihrf!1#syL2j4xeKKPTehTIEHS>l~~ zYYNtB^2BQ=9RYOQMq<2ELab4Y)eH~bc^QQ}b|L5WCZ7UCKI7vIoaubUN->o~SOGdB zgPUoXqN-=Ftf;3s8WSF{SHBIVgx&j)Ct=*-P!`Fb_CDAw66OpYC*RJOLg_XD+POhp zZ_qnlMYNRHnQco<71o3qH$1vr6mCEIM@=ILh1o|WJPNGzDt2TerKWT>3*K9ZW%{{6|UOew+6koSTn$i{+KrvzC zwIc_TjN7UBS}+3z-G!E5)fM6n=;6_v#kD$nHp826OuNTf518{aP0 zFoq1Llxs&(&0DxNSWVdXu)3JN-+_=t(+d)^_;ai@3CYz7W5g^_X6=s}4H=^|`~P8# zHiGA_`T_;Zy(p+WZ-mZ2r`b*|c>y8Ttjx|j?NR|((g77PCwTi$KJ2W}u2J;sKPz

=lY@;SXXZ_O>udZ#W? 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�Xw6@vh#ujV5)NHLSZ4!LV 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%0D6Q* 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